69#define DEBUG_TYPE "asm-parser"
76enum class ImplicitItModeTy {
Always,
Never, ARMOnly, ThumbOnly };
79 "arm-implicit-it",
cl::init(ImplicitItModeTy::ARMOnly),
80 cl::desc(
"Allow conditional instructions outside of an IT block"),
82 "Accept in both ISAs, emit implicit ITs in Thumb"),
84 "Warn in ARM, reject in Thumb"),
86 "Accept in ARM, reject in Thumb"),
87 clEnumValN(ImplicitItModeTy::ThumbOnly,
"thumb",
88 "Warn in ARM, emit implicit ITs in Thumb")));
93enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
95static inline unsigned extractITMaskBit(
unsigned Mask,
unsigned Position) {
102 return (Mask >> (5 - Position) & 1);
111 Locs PersonalityLocs;
112 Locs PersonalityIndexLocs;
113 Locs HandlerDataLocs;
119 bool hasFnStart()
const {
return !FnStartLocs.empty(); }
120 bool cantUnwind()
const {
return !CantUnwindLocs.empty(); }
121 bool hasHandlerData()
const {
return !HandlerDataLocs.empty(); }
123 bool hasPersonality()
const {
124 return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
127 void recordFnStart(
SMLoc L) { FnStartLocs.push_back(L); }
128 void recordCantUnwind(
SMLoc L) { CantUnwindLocs.push_back(L); }
129 void recordPersonality(
SMLoc L) { PersonalityLocs.push_back(L); }
130 void recordHandlerData(
SMLoc L) { HandlerDataLocs.push_back(L); }
131 void recordPersonalityIndex(
SMLoc L) { PersonalityIndexLocs.push_back(L); }
136 void emitFnStartLocNotes()
const {
138 Parser.
Note(
Loc,
".fnstart was specified here");
141 void emitCantUnwindLocNotes()
const {
143 Parser.
Note(
Loc,
".cantunwind was specified here");
146 void emitHandlerDataLocNotes()
const {
148 Parser.
Note(
Loc,
".handlerdata was specified here");
151 void emitPersonalityLocNotes()
const {
153 PE = PersonalityLocs.end(),
154 PII = PersonalityIndexLocs.begin(),
155 PIE = PersonalityIndexLocs.end();
156 PI != PE || PII != PIE;) {
157 if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
158 Parser.
Note(*PI++,
".personality was specified here");
159 else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
160 Parser.
Note(*PII++,
".personalityindex was specified here");
163 "at the same location");
168 FnStartLocs = Locs();
169 CantUnwindLocs = Locs();
170 PersonalityLocs = Locs();
171 HandlerDataLocs = Locs();
172 PersonalityIndexLocs = Locs();
178class ARMMnemonicSets {
189 return CDE.
count(Mnemonic);
194 bool isVPTPredicableCDEInstr(
StringRef Mnemonic) {
197 return CDEWithVPTSuffix.
count(Mnemonic);
202 bool isITPredicableCDEInstr(
StringRef Mnemonic) {
212 bool isCDEDualRegInstr(
StringRef Mnemonic) {
215 return Mnemonic ==
"cx1d" || Mnemonic ==
"cx1da" ||
216 Mnemonic ==
"cx2d" || Mnemonic ==
"cx2da" ||
217 Mnemonic ==
"cx3d" || Mnemonic ==
"cx3da";
222 for (
StringRef Mnemonic: {
"cx1",
"cx1a",
"cx1d",
"cx1da",
223 "cx2",
"cx2a",
"cx2d",
"cx2da",
224 "cx3",
"cx3a",
"cx3d",
"cx3da", })
227 {
"vcx1",
"vcx1a",
"vcx2",
"vcx2a",
"vcx3",
"vcx3a"}) {
229 CDEWithVPTSuffix.
insert(Mnemonic);
230 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"t");
231 CDEWithVPTSuffix.
insert(std::string(Mnemonic) +
"e");
241 assert(getParser().getStreamer().getTargetStreamer() &&
242 "do not have a target streamer");
250 bool NextSymbolIsThumb;
252 bool useImplicitITThumb()
const {
253 return ImplicitItMode == ImplicitItModeTy::Always ||
254 ImplicitItMode == ImplicitItModeTy::ThumbOnly;
257 bool useImplicitITARM()
const {
258 return ImplicitItMode == ImplicitItModeTy::Always ||
259 ImplicitItMode == ImplicitItModeTy::ARMOnly;
274 unsigned CurPosition;
289 void onEndOfFile()
override {
290 flushPendingInstructions(getParser().getStreamer());
293 void flushPendingInstructions(
MCStreamer &Out)
override {
294 if (!inImplicitITBlock()) {
304 Out.emitInstruction(ITInst, getSTI());
308 for (
const MCInst &Inst : PendingConditionalInsts) {
309 Out.emitInstruction(Inst, getSTI());
311 PendingConditionalInsts.clear();
315 ITState.CurPosition = ~0U;
318 bool inITBlock() {
return ITState.CurPosition != ~0U; }
319 bool inExplicitITBlock() {
return inITBlock() && ITState.IsExplicit; }
320 bool inImplicitITBlock() {
return inITBlock() && !ITState.IsExplicit; }
322 bool lastInITBlock() {
326 void forwardITPosition() {
327 if (!inITBlock())
return;
332 if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
333 ITState.CurPosition = ~0U;
337 void rewindImplicitITPosition() {
338 assert(inImplicitITBlock());
339 assert(ITState.CurPosition > 1);
340 ITState.CurPosition--;
342 unsigned NewMask = 0;
343 NewMask |= ITState.Mask & (0xC << TZ);
344 NewMask |= 0x2 << TZ;
345 ITState.Mask = NewMask;
350 void discardImplicitITBlock() {
351 assert(inImplicitITBlock());
352 assert(ITState.CurPosition == 1);
353 ITState.CurPosition = ~0U;
358 unsigned MaskBit = extractITMaskBit(ITState.Mask, ITState.CurPosition);
364 void invertCurrentITCondition() {
365 if (ITState.CurPosition == 1) {
368 ITState.Mask ^= 1 << (5 - ITState.CurPosition);
373 bool isITBlockFull() {
374 return inITBlock() && (ITState.Mask & 1);
380 assert(inImplicitITBlock());
385 unsigned NewMask = 0;
387 NewMask |= ITState.Mask & (0xE << TZ);
389 NewMask |= (
Cond != ITState.Cond) << TZ;
391 NewMask |= 1 << (TZ - 1);
392 ITState.Mask = NewMask;
396 void startImplicitITBlock() {
400 ITState.CurPosition = 1;
401 ITState.IsExplicit =
false;
412 ITState.CurPosition = 0;
413 ITState.IsExplicit =
true;
418 unsigned CurPosition;
420 bool inVPTBlock() {
return VPTState.CurPosition != ~0U; }
421 void forwardVPTPosition() {
422 if (!inVPTBlock())
return;
424 if (++VPTState.CurPosition == 5 - TZ)
425 VPTState.CurPosition = ~0U;
429 return getParser().Note(L,
Msg,
Range);
433 return getParser().Warning(L,
Msg,
Range);
437 return getParser().Error(L,
Msg,
Range);
441 unsigned MnemonicOpsEndInd,
unsigned ListIndex,
442 bool IsARPop =
false);
444 unsigned MnemonicOpsEndInd,
unsigned ListIndex);
446 MCRegister tryParseRegister(
bool AllowOutofBoundReg =
false);
449 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
450 bool parseRegisterList(
OperandVector &,
bool EnforceOrder =
true,
451 bool AllowRAAC =
false,
bool IsLazyLoadStore =
false,
452 bool IsVSCCLRM =
false);
455 bool parseImmExpr(int64_t &Out);
458 unsigned &ShiftAmount);
459 bool parseLiteralValues(
unsigned Size,
SMLoc L);
460 bool parseDirectiveThumb(
SMLoc L);
461 bool parseDirectiveARM(
SMLoc L);
462 bool parseDirectiveThumbFunc(
SMLoc L);
463 bool parseDirectiveCode(
SMLoc L);
464 bool parseDirectiveSyntax(
SMLoc L);
466 bool parseDirectiveUnreq(
SMLoc L);
467 bool parseDirectiveArch(
SMLoc L);
468 bool parseDirectiveEabiAttr(
SMLoc L);
469 bool parseDirectiveCPU(
SMLoc L);
470 bool parseDirectiveFPU(
SMLoc L);
471 bool parseDirectiveFnStart(
SMLoc L);
472 bool parseDirectiveFnEnd(
SMLoc L);
473 bool parseDirectiveCantUnwind(
SMLoc L);
474 bool parseDirectivePersonality(
SMLoc L);
475 bool parseDirectiveHandlerData(
SMLoc L);
476 bool parseDirectiveSetFP(
SMLoc L);
477 bool parseDirectivePad(
SMLoc L);
478 bool parseDirectiveRegSave(
SMLoc L,
bool IsVector);
479 bool parseDirectiveInst(
SMLoc L,
char Suffix =
'\0');
480 bool parseDirectiveLtorg(
SMLoc L);
481 bool parseDirectiveEven(
SMLoc L);
482 bool parseDirectivePersonalityIndex(
SMLoc L);
483 bool parseDirectiveUnwindRaw(
SMLoc L);
484 bool parseDirectiveTLSDescSeq(
SMLoc L);
485 bool parseDirectiveMovSP(
SMLoc L);
486 bool parseDirectiveObjectArch(
SMLoc L);
487 bool parseDirectiveArchExtension(
SMLoc L);
488 bool parseDirectiveAlign(
SMLoc L);
489 bool parseDirectiveThumbSet(
SMLoc L);
491 bool parseDirectiveSEHAllocStack(
SMLoc L,
bool Wide);
492 bool parseDirectiveSEHSaveRegs(
SMLoc L,
bool Wide);
493 bool parseDirectiveSEHSaveSP(
SMLoc L);
494 bool parseDirectiveSEHSaveFRegs(
SMLoc L);
495 bool parseDirectiveSEHSaveLR(
SMLoc L);
497 bool parseDirectiveSEHNop(
SMLoc L,
bool Wide);
498 bool parseDirectiveSEHEpilogStart(
SMLoc L,
bool Condition);
499 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
500 bool parseDirectiveSEHCustom(
SMLoc L);
502 std::unique_ptr<ARMOperand> defaultCondCodeOp();
503 std::unique_ptr<ARMOperand> defaultCCOutOp();
504 std::unique_ptr<ARMOperand> defaultVPTPredOp();
510 bool &CarrySetting,
unsigned &ProcessorIMod,
513 StringRef FullInst,
bool &CanAcceptCarrySet,
514 bool &CanAcceptPredicationCode,
515 bool &CanAcceptVPTPredicationCode);
518 void tryConvertingToTwoOperandForm(
StringRef Mnemonic,
521 unsigned MnemonicOpsEndInd);
524 unsigned MnemonicOpsEndInd);
528 return getSTI().hasFeature(ARM::ModeThumb);
531 bool isThumbOne()
const {
532 return isThumb() && !getSTI().hasFeature(ARM::FeatureThumb2);
535 bool isThumbTwo()
const {
536 return isThumb() && getSTI().hasFeature(ARM::FeatureThumb2);
539 bool hasThumb()
const {
540 return getSTI().hasFeature(ARM::HasV4TOps);
543 bool hasThumb2()
const {
544 return getSTI().hasFeature(ARM::FeatureThumb2);
547 bool hasV6Ops()
const {
548 return getSTI().hasFeature(ARM::HasV6Ops);
551 bool hasV6T2Ops()
const {
552 return getSTI().hasFeature(ARM::HasV6T2Ops);
555 bool hasV6MOps()
const {
556 return getSTI().hasFeature(ARM::HasV6MOps);
559 bool hasV7Ops()
const {
560 return getSTI().hasFeature(ARM::HasV7Ops);
563 bool hasV8Ops()
const {
564 return getSTI().hasFeature(ARM::HasV8Ops);
567 bool hasV8MBaseline()
const {
568 return getSTI().hasFeature(ARM::HasV8MBaselineOps);
571 bool hasV8MMainline()
const {
572 return getSTI().hasFeature(ARM::HasV8MMainlineOps);
574 bool hasV8_1MMainline()
const {
575 return getSTI().hasFeature(ARM::HasV8_1MMainlineOps);
577 bool hasMVEFloat()
const {
578 return getSTI().hasFeature(ARM::HasMVEFloatOps);
580 bool hasCDE()
const {
581 return getSTI().hasFeature(ARM::HasCDEOps);
583 bool has8MSecExt()
const {
584 return getSTI().hasFeature(ARM::Feature8MSecExt);
587 bool hasARM()
const {
588 return !getSTI().hasFeature(ARM::FeatureNoARM);
591 bool hasDSP()
const {
592 return getSTI().hasFeature(ARM::FeatureDSP);
595 bool hasD32()
const {
596 return getSTI().hasFeature(ARM::FeatureD32);
599 bool hasV8_1aOps()
const {
600 return getSTI().hasFeature(ARM::HasV8_1aOps);
603 bool hasRAS()
const {
604 return getSTI().hasFeature(ARM::FeatureRAS);
609 auto FB = ComputeAvailableFeatures(STI.
ToggleFeature(ARM::ModeThumb));
610 setAvailableFeatures(FB);
613 void FixModeAfterArchChange(
bool WasThumb,
SMLoc Loc);
615 bool isMClass()
const {
616 return getSTI().hasFeature(ARM::FeatureMClass);
622#define GET_ASSEMBLER_HEADER
623#include "ARMGenAsmMatcher.inc"
654 ParseStatus parseVectorLane(VectorLaneTy &LaneKind,
unsigned &Index,
663 unsigned MnemonicOpsEndInd);
665 unsigned MnemonicOpsEndInd, MCStreamer &Out);
666 bool shouldOmitVectorPredicateOperand(StringRef Mnemonic,
668 unsigned MnemonicOpsEndInd);
669 bool isITBlockTerminator(MCInst &Inst)
const;
672 unsigned MnemonicOpsEndInd);
674 bool ARMMode,
bool Writeback,
675 unsigned MnemonicOpsEndInd);
678 enum ARMMatchResultTy {
679 Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
680 Match_RequiresNotITBlock,
682 Match_RequiresThumb2,
684 Match_RequiresFlagSetting,
685#define GET_OPERAND_DIAGNOSTIC_TYPES
686#include "ARMGenAsmMatcher.inc"
690 ARMAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
691 const MCInstrInfo &MII)
692 : MCTargetAsmParser(STI, MII), UC(Parser), MS(STI) {
699 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
703 getTargetStreamer().emitTargetAttributes(STI);
706 ITState.CurPosition = ~0
U;
708 VPTState.CurPosition = ~0
U;
710 NextSymbolIsThumb =
false;
714 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
715 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
716 SMLoc &EndLoc)
override;
717 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
719 bool ParseDirective(AsmToken DirectiveID)
override;
721 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
722 unsigned Kind)
override;
723 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
725 checkEarlyTargetMatchPredicate(MCInst &Inst,
728 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
731 bool MatchingInlineAsm)
override;
733 SmallVectorImpl<NearMissInfo> &NearMisses,
734 bool MatchingInlineAsm,
bool &EmitInITBlock,
737 struct NearMissMessage {
739 SmallString<128> Message;
742 const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
744 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
745 SmallVectorImpl<NearMissMessage> &NearMissesOut,
747 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
750 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
752 void onLabelParsed(MCSymbol *Symbol)
override;
754 const MCInstrDesc &getInstrDesc(
unsigned int Opcode)
const {
755 return MII.get(Opcode);
758 bool hasMVE()
const {
return getSTI().hasFeature(ARM::HasMVEIntegerOps); }
761 MCRegister getDRegFromQReg(MCRegister QReg)
const {
762 return MRI->getSubReg(QReg, ARM::dsub_0);
765 const MCRegisterInfo *getMRI()
const {
return MRI; }
770class ARMOperand :
public MCParsedAsmOperand {
781 k_InstSyncBarrierOpt,
782 k_TraceSyncBarrierOpt,
791 k_RegisterListWithAPSR,
794 k_FPSRegisterListWithVPR,
795 k_FPDRegisterListWithVPR,
797 k_VectorListAllLanes,
804 k_ConstantPoolImmediate,
805 k_BitfieldDescriptor,
809 SMLoc StartLoc, EndLoc, AlignmentLoc;
812 ARMAsmParser *Parser;
826 struct CoprocOptionOp {
868 struct VectorListOp {
875 struct VectorIndexOp {
885 MCRegister BaseRegNum;
888 const MCExpr *OffsetImm;
889 MCRegister OffsetRegNum;
894 unsigned isNegative : 1;
897 struct PostIdxRegOp {
904 struct ShifterImmOp {
909 struct RegShiftedRegOp {
916 struct RegShiftedImmOp {
940 struct CoprocOptionOp CoprocOption;
941 struct MBOptOp MBOpt;
942 struct ISBOptOp ISBOpt;
943 struct TSBOptOp TSBOpt;
944 struct ITMaskOp ITMask;
946 struct MMaskOp MMask;
947 struct BankedRegOp BankedReg;
950 struct VectorListOp VectorList;
951 struct VectorIndexOp VectorIndex;
953 struct MemoryOp Memory;
954 struct PostIdxRegOp PostIdxReg;
955 struct ShifterImmOp ShifterImm;
956 struct RegShiftedRegOp RegShiftedReg;
957 struct RegShiftedImmOp RegShiftedImm;
958 struct RotImmOp RotImm;
959 struct ModImmOp ModImm;
964 ARMOperand(KindTy K, ARMAsmParser &Parser) : Kind(
K), Parser(&Parser) {}
967 SMLoc getStartLoc()
const override {
return StartLoc; }
970 SMLoc getEndLoc()
const override {
return EndLoc; }
974 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
977 SMLoc getAlignmentLoc()
const {
978 assert(Kind == k_Memory &&
"Invalid access!");
983 assert(Kind == k_CondCode &&
"Invalid access!");
988 assert(isVPTPred() &&
"Invalid access!");
992 unsigned getCoproc()
const {
993 assert((Kind == k_CoprocNum || Kind == k_CoprocReg) &&
"Invalid access!");
998 assert(Kind == k_Token &&
"Invalid access!");
999 return StringRef(Tok.Data, Tok.Length);
1002 MCRegister
getReg()
const override {
1003 assert((Kind == k_Register || Kind == k_CCOut) &&
"Invalid access!");
1007 const SmallVectorImpl<MCRegister> &getRegList()
const {
1008 assert((Kind == k_RegisterList || Kind == k_RegisterListWithAPSR ||
1009 Kind == k_DPRRegisterList || Kind == k_SPRRegisterList ||
1010 Kind == k_FPSRegisterListWithVPR ||
1011 Kind == k_FPDRegisterListWithVPR) &&
1016 const MCExpr *
getImm()
const {
1017 assert(isImm() &&
"Invalid access!");
1021 const MCExpr *getConstantPoolImm()
const {
1022 assert(isConstantPoolImm() &&
"Invalid access!");
1026 unsigned getVectorIndex()
const {
1027 assert(Kind == k_VectorIndex &&
"Invalid access!");
1028 return VectorIndex.Val;
1032 assert(Kind == k_MemBarrierOpt &&
"Invalid access!");
1037 assert(Kind == k_InstSyncBarrierOpt &&
"Invalid access!");
1042 assert(Kind == k_TraceSyncBarrierOpt &&
"Invalid access!");
1047 assert(Kind == k_ProcIFlags &&
"Invalid access!");
1051 unsigned getMSRMask()
const {
1052 assert(Kind == k_MSRMask &&
"Invalid access!");
1056 unsigned getBankedReg()
const {
1057 assert(Kind == k_BankedReg &&
"Invalid access!");
1058 return BankedReg.Val;
1061 bool isCoprocNum()
const {
return Kind == k_CoprocNum; }
1062 bool isCoprocReg()
const {
return Kind == k_CoprocReg; }
1063 bool isCoprocOption()
const {
return Kind == k_CoprocOption; }
1064 bool isCondCode()
const {
return Kind == k_CondCode; }
1065 bool isVPTPred()
const {
return Kind == k_VPTPred; }
1066 bool isCCOut()
const {
return Kind == k_CCOut; }
1067 bool isITMask()
const {
return Kind == k_ITCondMask; }
1068 bool isITCondCode()
const {
return Kind == k_CondCode; }
1069 bool isImm()
const override {
1070 return Kind == k_Immediate;
1073 bool isARMBranchTarget()
const {
1074 if (!isImm())
return false;
1077 return CE->getValue() % 4 == 0;
1082 bool isThumbBranchTarget()
const {
1083 if (!isImm())
return false;
1086 return CE->getValue() % 2 == 0;
1092 template<
unsigned w
idth,
unsigned scale>
1093 bool isUnsignedOffset()
const {
1094 if (!isImm())
return false;
1097 int64_t Val =
CE->getValue();
1099 int64_t
Max =
Align * ((1LL << width) - 1);
1100 return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
1107 template<
unsigned w
idth,
unsigned scale>
1108 bool isSignedOffset()
const {
1109 if (!isImm())
return false;
1112 int64_t Val =
CE->getValue();
1114 int64_t
Max =
Align * ((1LL << (width-1)) - 1);
1115 int64_t Min = -
Align * (1LL << (width-1));
1116 return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
1123 bool isLEOffset()
const {
1124 if (!isImm())
return false;
1127 int64_t Val =
CE->getValue();
1128 return Val < 0 && Val >= -4094 && (Val & 1) == 0;
1137 bool isThumbMemPC()
const {
1142 if (!CE)
return false;
1143 Val =
CE->getValue();
1145 else if (isGPRMem()) {
1146 if(!Memory.OffsetImm || Memory.OffsetRegNum)
return false;
1147 if(Memory.BaseRegNum != ARM::PC)
return false;
1149 Val =
CE->getValue();
1154 return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
1157 bool isFPImm()
const {
1158 if (!isImm())
return false;
1166 template<
int64_t N,
int64_t M>
1167 bool isImmediate()
const {
1168 if (!isImm())
return false;
1170 if (!CE)
return false;
1171 int64_t
Value =
CE->getValue();
1175 template<
int64_t N,
int64_t M>
1176 bool isImmediateS4()
const {
1177 if (!isImm())
return false;
1179 if (!CE)
return false;
1180 int64_t
Value =
CE->getValue();
1186 Value == std::numeric_limits<int32_t>::min();
1188 template<
int64_t N,
int64_t M>
1189 bool isImmediateS2()
const {
1190 if (!isImm())
return false;
1192 if (!CE)
return false;
1193 int64_t
Value =
CE->getValue();
1196 bool isFBits16()
const {
1197 return isImmediate<0, 17>();
1199 bool isFBits32()
const {
1200 return isImmediate<1, 33>();
1202 bool isImm8s4()
const {
1203 return isImmediateS4<-1020, 1020>();
1205 bool isImm7s4()
const {
1206 return isImmediateS4<-508, 508>();
1208 bool isImm7Shift0()
const {
1209 return isImmediate<-127, 127>();
1211 bool isImm7Shift1()
const {
1212 return isImmediateS2<-255, 255>();
1214 bool isImm7Shift2()
const {
1215 return isImmediateS4<-511, 511>();
1217 bool isImm7()
const {
1218 return isImmediate<-127, 127>();
1220 bool isImm0_1020s4()
const {
1221 return isImmediateS4<0, 1020>();
1223 bool isImm0_508s4()
const {
1224 return isImmediateS4<0, 508>();
1226 bool isImm0_508s4Neg()
const {
1227 if (!isImm())
return false;
1229 if (!CE)
return false;
1230 int64_t
Value = -
CE->getValue();
1235 bool isImm0_4095Neg()
const {
1236 if (!isImm())
return false;
1238 if (!CE)
return false;
1243 if ((
CE->getValue() >> 32) > 0)
return false;
1244 uint32_t
Value = -
static_cast<uint32_t
>(
CE->getValue());
1248 bool isImm0_7()
const {
1249 return isImmediate<0, 7>();
1252 bool isImm1_16()
const {
1253 return isImmediate<1, 16>();
1256 bool isImm1_32()
const {
1257 return isImmediate<1, 32>();
1260 bool isImm8_255()
const {
1261 return isImmediate<8, 255>();
1264 bool isImm0_255Expr()
const {
1272 int64_t
Value =
CE->getValue();
1276 bool isImm256_65535Expr()
const {
1277 if (!isImm())
return false;
1281 if (!CE)
return true;
1282 int64_t
Value =
CE->getValue();
1286 bool isImm0_65535Expr()
const {
1287 if (!isImm())
return false;
1291 if (!CE)
return true;
1292 int64_t
Value =
CE->getValue();
1296 bool isImm24bit()
const {
1297 return isImmediate<0, 0xffffff + 1>();
1300 bool isImmThumbSR()
const {
1301 return isImmediate<1, 33>();
1304 bool isPKHLSLImm()
const {
1305 return isImmediate<0, 32>();
1308 bool isPKHASRImm()
const {
1309 return isImmediate<0, 33>();
1312 bool isAdrLabel()
const {
1319 if (!isImm())
return false;
1321 if (!CE)
return false;
1322 int64_t
Value =
CE->getValue();
1327 bool isT2SOImm()
const {
1334 return (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
1337 if (!isImm())
return false;
1339 if (!CE)
return false;
1340 int64_t
Value =
CE->getValue();
1344 bool isT2SOImmNot()
const {
1345 if (!isImm())
return false;
1347 if (!CE)
return false;
1348 int64_t
Value =
CE->getValue();
1353 bool isT2SOImmNeg()
const {
1354 if (!isImm())
return false;
1356 if (!CE)
return false;
1357 int64_t
Value =
CE->getValue();
1363 bool isSetEndImm()
const {
1364 if (!isImm())
return false;
1366 if (!CE)
return false;
1367 int64_t
Value =
CE->getValue();
1371 bool isReg()
const override {
return Kind == k_Register; }
1372 bool isRegList()
const {
return Kind == k_RegisterList; }
1373 bool isRegListWithAPSR()
const {
1374 return Kind == k_RegisterListWithAPSR || Kind == k_RegisterList;
1376 bool isDReg()
const {
1378 getARMMCRegisterClass(ARM::DPRRegClassID).contains(
Reg.RegNum);
1380 bool isQReg()
const {
1382 getARMMCRegisterClass(ARM::QPRRegClassID).contains(
Reg.RegNum);
1384 bool isDPRRegList()
const {
return Kind == k_DPRRegisterList; }
1385 bool isSPRRegList()
const {
return Kind == k_SPRRegisterList; }
1386 bool isFPSRegListWithVPR()
const {
return Kind == k_FPSRegisterListWithVPR; }
1387 bool isFPDRegListWithVPR()
const {
return Kind == k_FPDRegisterListWithVPR; }
1388 bool isToken()
const override {
return Kind == k_Token; }
1389 bool isMemBarrierOpt()
const {
return Kind == k_MemBarrierOpt; }
1390 bool isInstSyncBarrierOpt()
const {
return Kind == k_InstSyncBarrierOpt; }
1391 bool isTraceSyncBarrierOpt()
const {
return Kind == k_TraceSyncBarrierOpt; }
1392 bool isMem()
const override {
1393 return isGPRMem() || isMVEMem();
1395 bool isMVEMem()
const {
1396 if (Kind != k_Memory)
1398 if (Memory.BaseRegNum &&
1399 !getARMMCRegisterClass(ARM::GPRRegClassID)
1401 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1403 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::MQPRRegClassID)
1408 bool isGPRMem()
const {
1409 if (Kind != k_Memory)
1411 if (Memory.BaseRegNum &&
1412 !getARMMCRegisterClass(ARM::GPRRegClassID).
contains(Memory.BaseRegNum))
1414 if (Memory.OffsetRegNum && !getARMMCRegisterClass(ARM::GPRRegClassID)
1419 bool isShifterImm()
const {
return Kind == k_ShifterImmediate; }
1420 bool isRegShiftedReg()
const {
1421 return Kind == k_ShiftedRegister &&
1422 getARMMCRegisterClass(ARM::GPRRegClassID)
1423 .contains(RegShiftedReg.SrcReg) &&
1424 getARMMCRegisterClass(ARM::GPRRegClassID)
1425 .contains(RegShiftedReg.ShiftReg);
1427 bool isRegShiftedImm()
const {
1428 return Kind == k_ShiftedImmediate &&
1429 getARMMCRegisterClass(ARM::GPRRegClassID)
1430 .contains(RegShiftedImm.SrcReg);
1432 bool isRotImm()
const {
return Kind == k_RotateImmediate; }
1434 template<
unsigned Min,
unsigned Max>
1435 bool isPowerTwoInRange()
const {
1436 if (!isImm())
return false;
1438 if (!CE)
return false;
1439 int64_t
Value =
CE->getValue();
1443 bool isModImm()
const {
return Kind == k_ModifiedImmediate; }
1445 bool isModImmNot()
const {
1446 if (!isImm())
return false;
1448 if (!CE)
return false;
1449 int64_t
Value =
CE->getValue();
1453 bool isModImmNeg()
const {
1454 if (!isImm())
return false;
1456 if (!CE)
return false;
1457 int64_t
Value =
CE->getValue();
1462 bool isThumbModImmNeg1_7()
const {
1463 if (!isImm())
return false;
1465 if (!CE)
return false;
1466 int32_t
Value = -(int32_t)
CE->getValue();
1470 bool isThumbModImmNeg8_255()
const {
1471 if (!isImm())
return false;
1473 if (!CE)
return false;
1474 int32_t
Value = -(int32_t)
CE->getValue();
1478 bool isConstantPoolImm()
const {
return Kind == k_ConstantPoolImmediate; }
1479 bool isBitfield()
const {
return Kind == k_BitfieldDescriptor; }
1480 bool isPostIdxRegShifted()
const {
1481 return Kind == k_PostIndexRegister &&
1482 getARMMCRegisterClass(ARM::GPRRegClassID)
1483 .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 (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1504 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1505 (alignOK || Memory.Alignment ==
Alignment);
1507 bool isMemNoOffsetT2NoSp(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1511 if (!getARMMCRegisterClass(ARM::rGPRRegClassID).
contains(Memory.BaseRegNum))
1515 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1516 (alignOK || Memory.Alignment ==
Alignment);
1518 bool isMemNoOffsetT(
bool alignOK =
false,
unsigned Alignment = 0)
const {
1522 if (!getARMMCRegisterClass(ARM::tGPRRegClassID).
contains(Memory.BaseRegNum))
1526 return !Memory.OffsetRegNum && Memory.OffsetImm ==
nullptr &&
1527 (alignOK || Memory.Alignment ==
Alignment);
1529 bool isMemPCRelImm12()
const {
1530 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1533 if (Memory.BaseRegNum != ARM::PC)
1536 if (!Memory.OffsetImm)
return true;
1538 int64_t Val =
CE->getValue();
1539 return (Val > -4096 && Val < 4096) ||
1540 (Val == std::numeric_limits<int32_t>::min());
1545 bool isAlignedMemory()
const {
1546 return isMemNoOffset(
true);
1549 bool isAlignedMemoryNone()
const {
1550 return isMemNoOffset(
false, 0);
1553 bool isDupAlignedMemoryNone()
const {
1554 return isMemNoOffset(
false, 0);
1557 bool isAlignedMemory16()
const {
1558 if (isMemNoOffset(
false, 2))
1560 return isMemNoOffset(
false, 0);
1563 bool isDupAlignedMemory16()
const {
1564 if (isMemNoOffset(
false, 2))
1566 return isMemNoOffset(
false, 0);
1569 bool isAlignedMemory32()
const {
1570 if (isMemNoOffset(
false, 4))
1572 return isMemNoOffset(
false, 0);
1575 bool isDupAlignedMemory32()
const {
1576 if (isMemNoOffset(
false, 4))
1578 return isMemNoOffset(
false, 0);
1581 bool isAlignedMemory64()
const {
1582 if (isMemNoOffset(
false, 8))
1584 return isMemNoOffset(
false, 0);
1587 bool isDupAlignedMemory64()
const {
1588 if (isMemNoOffset(
false, 8))
1590 return isMemNoOffset(
false, 0);
1593 bool isAlignedMemory64or128()
const {
1594 if (isMemNoOffset(
false, 8))
1596 if (isMemNoOffset(
false, 16))
1598 return isMemNoOffset(
false, 0);
1601 bool isDupAlignedMemory64or128()
const {
1602 if (isMemNoOffset(
false, 8))
1604 if (isMemNoOffset(
false, 16))
1606 return isMemNoOffset(
false, 0);
1609 bool isAlignedMemory64or128or256()
const {
1610 if (isMemNoOffset(
false, 8))
1612 if (isMemNoOffset(
false, 16))
1614 if (isMemNoOffset(
false, 32))
1616 return isMemNoOffset(
false, 0);
1619 bool isAddrMode2()
const {
1620 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1622 if (Memory.OffsetRegNum)
return true;
1624 if (!Memory.OffsetImm)
return true;
1626 int64_t Val =
CE->getValue();
1627 return Val > -4096 && Val < 4096;
1632 bool isAM2OffsetImm()
const {
1633 if (!isImm())
return false;
1636 if (!CE)
return false;
1637 int64_t Val =
CE->getValue();
1638 return (Val == std::numeric_limits<int32_t>::min()) ||
1639 (Val > -4096 && Val < 4096);
1642 bool isAddrMode3()
const {
1648 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1652 if (Memory.OffsetRegNum)
return true;
1654 if (!Memory.OffsetImm)
return true;
1656 int64_t Val =
CE->getValue();
1659 return (Val > -256 && Val < 256) ||
1660 Val == std::numeric_limits<int32_t>::min();
1665 bool isAM3Offset()
const {
1672 if (!CE)
return false;
1673 int64_t Val =
CE->getValue();
1675 return (Val > -256 && Val < 256) ||
1676 Val == std::numeric_limits<int32_t>::min();
1679 bool isAddrMode5()
const {
1685 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1687 if (Memory.OffsetRegNum)
return false;
1689 if (!Memory.OffsetImm)
return true;
1691 int64_t Val =
CE->getValue();
1692 return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
1693 Val == std::numeric_limits<int32_t>::min();
1698 bool isAddrMode5FP16()
const {
1704 if (!isGPRMem() || Memory.Alignment != 0)
return false;
1706 if (Memory.OffsetRegNum)
return false;
1708 if (!Memory.OffsetImm)
return true;
1710 int64_t Val =
CE->getValue();
1711 return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
1712 Val == std::numeric_limits<int32_t>::min();
1717 bool isMemTBB()
const {
1718 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1724 bool isMemTBH()
const {
1725 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1726 Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm != 1 ||
1727 Memory.Alignment != 0 )
1732 bool isMemRegOffset()
const {
1733 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
1738 bool isT2MemRegOffset()
const {
1739 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1740 Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
1745 if (Memory.ShiftType !=
ARM_AM::lsl || Memory.ShiftImm > 3)
1750 bool isMemThumbRR()
const {
1753 if (!isGPRMem() || !Memory.OffsetRegNum || Memory.isNegative ||
1760 bool isMemThumbRIs4()
const {
1761 if (!isGPRMem() || Memory.OffsetRegNum ||
1765 if (!Memory.OffsetImm)
return true;
1767 int64_t Val =
CE->getValue();
1768 return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1773 bool isMemThumbRIs2()
const {
1774 if (!isGPRMem() || Memory.OffsetRegNum ||
1778 if (!Memory.OffsetImm)
return true;
1780 int64_t Val =
CE->getValue();
1781 return Val >= 0 && Val <= 62 && (Val % 2) == 0;
1786 bool isMemThumbRIs1()
const {
1787 if (!isGPRMem() || Memory.OffsetRegNum ||
1791 if (!Memory.OffsetImm)
return true;
1793 int64_t Val =
CE->getValue();
1794 return Val >= 0 && Val <= 31;
1799 bool isMemThumbSPI()
const {
1800 if (!isGPRMem() || Memory.OffsetRegNum || Memory.BaseRegNum != ARM::SP ||
1801 Memory.Alignment != 0)
1804 if (!Memory.OffsetImm)
return true;
1806 int64_t Val =
CE->getValue();
1807 return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1812 bool isMemImm8s4Offset()
const {
1818 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1821 if (!Memory.OffsetImm)
return true;
1823 int64_t Val =
CE->getValue();
1825 return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
1826 Val == std::numeric_limits<int32_t>::min();
1831 bool isMemImm7s4Offset()
const {
1837 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1838 !getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1842 if (!Memory.OffsetImm)
return true;
1844 int64_t Val =
CE->getValue();
1846 return (Val >= -508 && Val <= 508 && (Val & 3) == 0) || Val == INT32_MIN;
1851 bool isMemImm0_1020s4Offset()
const {
1852 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1855 if (!Memory.OffsetImm)
return true;
1857 int64_t Val =
CE->getValue();
1858 return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1863 bool isMemImm8Offset()
const {
1864 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1867 if (Memory.BaseRegNum == ARM::PC)
return false;
1869 if (!Memory.OffsetImm)
return true;
1871 int64_t Val =
CE->getValue();
1872 return (Val == std::numeric_limits<int32_t>::min()) ||
1873 (Val > -256 && Val < 256);
1878 template<
unsigned Bits,
unsigned RegClassID>
1879 bool isMemImm7ShiftedOffset()
const {
1880 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0 ||
1881 !getARMMCRegisterClass(RegClassID).
contains(Memory.BaseRegNum))
1887 if (!Memory.OffsetImm)
return true;
1889 int64_t Val =
CE->getValue();
1893 if (Val == INT32_MIN)
1896 unsigned Divisor = 1U <<
Bits;
1899 if (Val % Divisor != 0)
1904 return (Val >= -127 && Val <= 127);
1909 template <
int shift>
bool isMemRegRQOffset()
const {
1910 if (!isMVEMem() || Memory.OffsetImm !=
nullptr || Memory.Alignment != 0)
1913 if (!getARMMCRegisterClass(ARM::GPRnopcRegClassID)
1916 if (!getARMMCRegisterClass(ARM::MQPRRegClassID)
1924 (Memory.ShiftType !=
ARM_AM::uxtw || Memory.ShiftImm != shift))
1930 template <
int shift>
bool isMemRegQOffset()
const {
1931 if (!isMVEMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1934 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(Memory.BaseRegNum))
1937 if (!Memory.OffsetImm)
1939 static_assert(shift < 56,
1940 "Such that we dont shift by a value higher than 62");
1942 int64_t Val =
CE->getValue();
1945 if ((Val & ((1U << shift) - 1)) != 0)
1951 int64_t
Range = (1U << (7 + shift)) - 1;
1952 return (Val == INT32_MIN) || (Val > -
Range && Val <
Range);
1957 bool isMemPosImm8Offset()
const {
1958 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1961 if (!Memory.OffsetImm)
return true;
1963 int64_t Val =
CE->getValue();
1964 return Val >= 0 && Val < 256;
1969 bool isMemNegImm8Offset()
const {
1970 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1973 if (Memory.BaseRegNum == ARM::PC)
return false;
1975 if (!Memory.OffsetImm)
return false;
1977 int64_t Val =
CE->getValue();
1978 return (Val == std::numeric_limits<int32_t>::min()) ||
1979 (Val > -256 && Val < 0);
1984 bool isMemUImm12Offset()
const {
1985 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
1988 if (!Memory.OffsetImm)
return true;
1990 int64_t Val =
CE->getValue();
1991 return (Val >= 0 && Val < 4096);
1996 bool isMemImm12Offset()
const {
2004 if (!isGPRMem() || Memory.OffsetRegNum || Memory.Alignment != 0)
2007 if (!Memory.OffsetImm)
return true;
2009 int64_t Val =
CE->getValue();
2010 return (Val > -4096 && Val < 4096) ||
2011 (Val == std::numeric_limits<int32_t>::min());
2018 bool isConstPoolAsmImm()
const {
2021 return (isConstantPoolImm());
2024 bool isPostIdxImm8()
const {
2025 if (!isImm())
return false;
2027 if (!CE)
return false;
2028 int64_t Val =
CE->getValue();
2029 return (Val > -256 && Val < 256) ||
2030 (Val == std::numeric_limits<int32_t>::min());
2033 bool isPostIdxImm8s4()
const {
2034 if (!isImm())
return false;
2036 if (!CE)
return false;
2037 int64_t Val =
CE->getValue();
2038 return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
2039 (Val == std::numeric_limits<int32_t>::min());
2042 bool isMSRMask()
const {
return Kind == k_MSRMask; }
2043 bool isBankedReg()
const {
return Kind == k_BankedReg; }
2044 bool isProcIFlags()
const {
return Kind == k_ProcIFlags; }
2047 bool isAnyVectorList()
const {
2048 return Kind == k_VectorList || Kind == k_VectorListAllLanes ||
2049 Kind == k_VectorListIndexed;
2052 bool isVectorList()
const {
return Kind == k_VectorList; }
2054 bool isSingleSpacedVectorList()
const {
2055 return Kind == k_VectorList && !VectorList.isDoubleSpaced;
2058 bool isDoubleSpacedVectorList()
const {
2059 return Kind == k_VectorList && VectorList.isDoubleSpaced;
2062 bool isVecListOneD()
const {
2064 if (isDReg() && !Parser->hasMVE())
2066 if (!isSingleSpacedVectorList())
return false;
2067 return VectorList.Count == 1;
2070 bool isVecListTwoMQ()
const {
2071 return isSingleSpacedVectorList() && VectorList.Count == 2 &&
2072 getARMMCRegisterClass(ARM::MQPRRegClassID)
2073 .contains(VectorList.RegNum);
2076 bool isVecListDPair()
const {
2079 if (isQReg() && !Parser->hasMVE())
2081 if (!isSingleSpacedVectorList())
return false;
2082 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2086 bool isVecListThreeD()
const {
2087 if (!isSingleSpacedVectorList())
return false;
2088 return VectorList.Count == 3;
2091 bool isVecListFourD()
const {
2092 if (!isSingleSpacedVectorList())
return false;
2093 return VectorList.Count == 4;
2096 bool isVecListDPairSpaced()
const {
2097 if (Kind != k_VectorList)
return false;
2098 if (isSingleSpacedVectorList())
return false;
2099 return (getARMMCRegisterClass(ARM::DPairSpcRegClassID)
2103 bool isVecListThreeQ()
const {
2104 if (!isDoubleSpacedVectorList())
return false;
2105 return VectorList.Count == 3;
2108 bool isVecListFourQ()
const {
2109 if (!isDoubleSpacedVectorList())
return false;
2110 return VectorList.Count == 4;
2113 bool isVecListFourMQ()
const {
2114 return isSingleSpacedVectorList() && VectorList.Count == 4 &&
2115 getARMMCRegisterClass(ARM::MQPRRegClassID)
2116 .contains(VectorList.RegNum);
2119 bool isSingleSpacedVectorAllLanes()
const {
2120 return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
2123 bool isDoubleSpacedVectorAllLanes()
const {
2124 return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
2127 bool isVecListOneDAllLanes()
const {
2128 if (!isSingleSpacedVectorAllLanes())
return false;
2129 return VectorList.Count == 1;
2132 bool isVecListDPairAllLanes()
const {
2133 if (!isSingleSpacedVectorAllLanes())
return false;
2134 return (getARMMCRegisterClass(ARM::DPairRegClassID)
2138 bool isVecListDPairSpacedAllLanes()
const {
2139 if (!isDoubleSpacedVectorAllLanes())
return false;
2140 return VectorList.Count == 2;
2143 bool isVecListThreeDAllLanes()
const {
2144 if (!isSingleSpacedVectorAllLanes())
return false;
2145 return VectorList.Count == 3;
2148 bool isVecListThreeQAllLanes()
const {
2149 if (!isDoubleSpacedVectorAllLanes())
return false;
2150 return VectorList.Count == 3;
2153 bool isVecListFourDAllLanes()
const {
2154 if (!isSingleSpacedVectorAllLanes())
return false;
2155 return VectorList.Count == 4;
2158 bool isVecListFourQAllLanes()
const {
2159 if (!isDoubleSpacedVectorAllLanes())
return false;
2160 return VectorList.Count == 4;
2163 bool isSingleSpacedVectorIndexed()
const {
2164 return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
2167 bool isDoubleSpacedVectorIndexed()
const {
2168 return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
2171 bool isVecListOneDByteIndexed()
const {
2172 if (!isSingleSpacedVectorIndexed())
return false;
2173 return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
2176 bool isVecListOneDHWordIndexed()
const {
2177 if (!isSingleSpacedVectorIndexed())
return false;
2178 return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
2181 bool isVecListOneDWordIndexed()
const {
2182 if (!isSingleSpacedVectorIndexed())
return false;
2183 return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
2186 bool isVecListTwoDByteIndexed()
const {
2187 if (!isSingleSpacedVectorIndexed())
return false;
2188 return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
2191 bool isVecListTwoDHWordIndexed()
const {
2192 if (!isSingleSpacedVectorIndexed())
return false;
2193 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2196 bool isVecListTwoQWordIndexed()
const {
2197 if (!isDoubleSpacedVectorIndexed())
return false;
2198 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2201 bool isVecListTwoQHWordIndexed()
const {
2202 if (!isDoubleSpacedVectorIndexed())
return false;
2203 return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
2206 bool isVecListTwoDWordIndexed()
const {
2207 if (!isSingleSpacedVectorIndexed())
return false;
2208 return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
2211 bool isVecListThreeDByteIndexed()
const {
2212 if (!isSingleSpacedVectorIndexed())
return false;
2213 return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
2216 bool isVecListThreeDHWordIndexed()
const {
2217 if (!isSingleSpacedVectorIndexed())
return false;
2218 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2221 bool isVecListThreeQWordIndexed()
const {
2222 if (!isDoubleSpacedVectorIndexed())
return false;
2223 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2226 bool isVecListThreeQHWordIndexed()
const {
2227 if (!isDoubleSpacedVectorIndexed())
return false;
2228 return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
2231 bool isVecListThreeDWordIndexed()
const {
2232 if (!isSingleSpacedVectorIndexed())
return false;
2233 return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
2236 bool isVecListFourDByteIndexed()
const {
2237 if (!isSingleSpacedVectorIndexed())
return false;
2238 return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
2241 bool isVecListFourDHWordIndexed()
const {
2242 if (!isSingleSpacedVectorIndexed())
return false;
2243 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2246 bool isVecListFourQWordIndexed()
const {
2247 if (!isDoubleSpacedVectorIndexed())
return false;
2248 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2251 bool isVecListFourQHWordIndexed()
const {
2252 if (!isDoubleSpacedVectorIndexed())
return false;
2253 return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
2256 bool isVecListFourDWordIndexed()
const {
2257 if (!isSingleSpacedVectorIndexed())
return false;
2258 return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
2261 bool isVectorIndex()
const {
return Kind == k_VectorIndex; }
2263 template <
unsigned NumLanes>
2264 bool isVectorIndexInRange()
const {
2265 if (Kind != k_VectorIndex)
return false;
2266 return VectorIndex.Val < NumLanes;
2269 bool isVectorIndex8()
const {
return isVectorIndexInRange<8>(); }
2270 bool isVectorIndex16()
const {
return isVectorIndexInRange<4>(); }
2271 bool isVectorIndex32()
const {
return isVectorIndexInRange<2>(); }
2272 bool isVectorIndex64()
const {
return isVectorIndexInRange<1>(); }
2274 template<
int PermittedValue,
int OtherPermittedValue>
2275 bool isMVEPairVectorIndex()
const {
2276 if (Kind != k_VectorIndex)
return false;
2277 return VectorIndex.Val == PermittedValue ||
2278 VectorIndex.Val == OtherPermittedValue;
2281 bool isNEONi8splat()
const {
2282 if (!isImm())
return false;
2285 if (!CE)
return false;
2286 int64_t
Value =
CE->getValue();
2293 if (isNEONByteReplicate(2))
2299 if (!CE)
return false;
2300 unsigned Value =
CE->getValue();
2304 bool isNEONi16splatNot()
const {
2309 if (!CE)
return false;
2310 unsigned Value =
CE->getValue();
2315 if (isNEONByteReplicate(4))
2321 if (!CE)
return false;
2322 unsigned Value =
CE->getValue();
2326 bool isNEONi32splatNot()
const {
2331 if (!CE)
return false;
2332 unsigned Value =
CE->getValue();
2336 static bool isValidNEONi32vmovImm(int64_t
Value) {
2339 return ((
Value & 0xffffffffffffff00) == 0) ||
2340 ((
Value & 0xffffffffffff00ff) == 0) ||
2341 ((
Value & 0xffffffffff00ffff) == 0) ||
2342 ((
Value & 0xffffffff00ffffff) == 0) ||
2343 ((
Value & 0xffffffffffff00ff) == 0xff) ||
2344 ((
Value & 0xffffffffff00ffff) == 0xffff);
2347 bool isNEONReplicate(
unsigned Width,
unsigned NumElems,
bool Inv)
const {
2348 assert((Width == 8 || Width == 16 || Width == 32) &&
2349 "Invalid element width");
2350 assert(NumElems * Width <= 64 &&
"Invalid result width");
2358 int64_t
Value =
CE->getValue();
2366 if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
2368 if (Width == 32 && !isValidNEONi32vmovImm(Elem))
2371 for (
unsigned i = 1; i < NumElems; ++i) {
2373 if ((
Value & Mask) != Elem)
2379 bool isNEONByteReplicate(
unsigned NumBytes)
const {
2380 return isNEONReplicate(8, NumBytes,
false);
2383 static void checkNeonReplicateArgs(
unsigned FromW,
unsigned ToW) {
2384 assert((FromW == 8 || FromW == 16 || FromW == 32) &&
2385 "Invalid source width");
2386 assert((ToW == 16 || ToW == 32 || ToW == 64) &&
2387 "Invalid destination width");
2388 assert(FromW < ToW &&
"ToW is not less than FromW");
2391 template<
unsigned FromW,
unsigned ToW>
2392 bool isNEONmovReplicate()
const {
2393 checkNeonReplicateArgs(FromW, ToW);
2394 if (ToW == 64 && isNEONi64splat())
2396 return isNEONReplicate(FromW, ToW / FromW,
false);
2399 template<
unsigned FromW,
unsigned ToW>
2400 bool isNEONinvReplicate()
const {
2401 checkNeonReplicateArgs(FromW, ToW);
2402 return isNEONReplicate(FromW, ToW / FromW,
true);
2405 bool isNEONi32vmov()
const {
2406 if (isNEONByteReplicate(4))
2414 return isValidNEONi32vmovImm(
CE->getValue());
2417 bool isNEONi32vmovNeg()
const {
2418 if (!isImm())
return false;
2421 if (!CE)
return false;
2422 return isValidNEONi32vmovImm(~
CE->getValue());
2425 bool isNEONi64splat()
const {
2426 if (!isImm())
return false;
2429 if (!CE)
return false;
2432 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
2433 if ((
Value & 0xff) != 0 && (
Value & 0xff) != 0xff)
return false;
2437 template<
int64_t Angle,
int64_t Remainder>
2438 bool isComplexRotation()
const {
2439 if (!isImm())
return false;
2442 if (!CE)
return false;
2445 return (
Value % Angle == Remainder &&
Value <= 270);
2448 bool isMVELongShift()
const {
2449 if (!isImm())
return false;
2452 if (!CE)
return false;
2457 bool isMveSaturateOp()
const {
2458 if (!isImm())
return false;
2460 if (!CE)
return false;
2465 bool isITCondCodeNoAL()
const {
2466 if (!isITCondCode())
return false;
2471 bool isITCondCodeRestrictedI()
const {
2472 if (!isITCondCode())
2478 bool isITCondCodeRestrictedS()
const {
2479 if (!isITCondCode())
2486 bool isITCondCodeRestrictedU()
const {
2487 if (!isITCondCode())
2493 bool isITCondCodeRestrictedFP()
const {
2494 if (!isITCondCode())
2501 void setVecListDPair(
unsigned int DPair) {
2502 Kind = k_VectorList;
2503 VectorList.RegNum = DPair;
2504 VectorList.Count = 2;
2505 VectorList.isDoubleSpaced =
false;
2508 void setVecListOneD(
unsigned int DReg) {
2509 Kind = k_VectorList;
2510 VectorList.RegNum =
DReg;
2511 VectorList.Count = 1;
2512 VectorList.isDoubleSpaced =
false;
2515 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
2525 void addARMBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2526 assert(
N == 1 &&
"Invalid number of operands!");
2530 void addThumbBranchTargetOperands(MCInst &Inst,
unsigned N)
const {
2531 assert(
N == 1 &&
"Invalid number of operands!");
2535 void addCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2536 assert(
N == 2 &&
"Invalid number of operands!");
2542 void addVPTPredNOperands(MCInst &Inst,
unsigned N)
const {
2543 assert(
N == 3 &&
"Invalid number of operands!");
2545 unsigned RegNum = getVPTPred() ==
ARMVCC::None ? ARM::NoRegister : ARM::P0;
2550 void addVPTPredROperands(MCInst &Inst,
unsigned N)
const {
2551 assert(
N == 4 &&
"Invalid number of operands!");
2552 addVPTPredNOperands(Inst,
N-1);
2555 RegNum = ARM::NoRegister;
2558 auto &MCID = Parser->getInstrDesc(Inst.
getOpcode());
2559 int TiedOp = MCID.getOperandConstraint(NextOpIndex,
MCOI::TIED_TO);
2561 "Inactive register in vpred_r is not tied to an output!");
2567 void addCoprocNumOperands(MCInst &Inst,
unsigned N)
const {
2568 assert(
N == 1 &&
"Invalid number of operands!");
2572 void addCoprocRegOperands(MCInst &Inst,
unsigned N)
const {
2573 assert(
N == 1 &&
"Invalid number of operands!");
2577 void addCoprocOptionOperands(MCInst &Inst,
unsigned N)
const {
2578 assert(
N == 1 &&
"Invalid number of operands!");
2582 void addITMaskOperands(MCInst &Inst,
unsigned N)
const {
2583 assert(
N == 1 &&
"Invalid number of operands!");
2587 void addITCondCodeOperands(MCInst &Inst,
unsigned N)
const {
2588 assert(
N == 1 &&
"Invalid number of operands!");
2592 void addITCondCodeInvOperands(MCInst &Inst,
unsigned N)
const {
2593 assert(
N == 1 &&
"Invalid number of operands!");
2597 void addCCOutOperands(MCInst &Inst,
unsigned N)
const {
2598 assert(
N == 1 &&
"Invalid number of operands!");
2602 void addRegOperands(MCInst &Inst,
unsigned N)
const {
2603 assert(
N == 1 &&
"Invalid number of operands!");
2607 void addRegShiftedRegOperands(MCInst &Inst,
unsigned N)
const {
2608 assert(
N == 3 &&
"Invalid number of operands!");
2609 assert(isRegShiftedReg() &&
2610 "addRegShiftedRegOperands() on non-RegShiftedReg!");
2617 void addRegShiftedImmOperands(MCInst &Inst,
unsigned N)
const {
2618 assert(
N == 2 &&
"Invalid number of operands!");
2619 assert(isRegShiftedImm() &&
2620 "addRegShiftedImmOperands() on non-RegShiftedImm!");
2623 unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
2628 void addShifterImmOperands(MCInst &Inst,
unsigned N)
const {
2629 assert(
N == 1 &&
"Invalid number of operands!");
2634 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
2635 assert(
N == 1 &&
"Invalid number of operands!");
2636 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2637 for (MCRegister
Reg : RegList)
2641 void addRegListWithAPSROperands(MCInst &Inst,
unsigned N)
const {
2642 assert(
N == 1 &&
"Invalid number of operands!");
2643 const SmallVectorImpl<MCRegister> &RegList = getRegList();
2644 for (MCRegister
Reg : RegList)
2648 void addDPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2649 addRegListOperands(Inst,
N);
2652 void addSPRRegListOperands(MCInst &Inst,
unsigned N)
const {
2653 addRegListOperands(Inst,
N);
2656 void addFPSRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2657 addRegListOperands(Inst,
N);
2660 void addFPDRegListWithVPROperands(MCInst &Inst,
unsigned N)
const {
2661 addRegListOperands(Inst,
N);
2664 void addRotImmOperands(MCInst &Inst,
unsigned N)
const {
2665 assert(
N == 1 &&
"Invalid number of operands!");
2670 void addModImmOperands(MCInst &Inst,
unsigned N)
const {
2671 assert(
N == 1 &&
"Invalid number of operands!");
2675 return addImmOperands(Inst,
N);
2680 void addModImmNotOperands(MCInst &Inst,
unsigned N)
const {
2681 assert(
N == 1 &&
"Invalid number of operands!");
2687 void addModImmNegOperands(MCInst &Inst,
unsigned N)
const {
2688 assert(
N == 1 &&
"Invalid number of operands!");
2694 void addThumbModImmNeg8_255Operands(MCInst &Inst,
unsigned N)
const {
2695 assert(
N == 1 &&
"Invalid number of operands!");
2697 uint32_t Val = -
CE->getValue();
2701 void addThumbModImmNeg1_7Operands(MCInst &Inst,
unsigned N)
const {
2702 assert(
N == 1 &&
"Invalid number of operands!");
2704 uint32_t Val = -
CE->getValue();
2708 void addBitfieldOperands(MCInst &Inst,
unsigned N)
const {
2709 assert(
N == 1 &&
"Invalid number of operands!");
2714 uint32_t
Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
2715 (32 - (lsb + width)));
2719 void addImmOperands(MCInst &Inst,
unsigned N)
const {
2720 assert(
N == 1 &&
"Invalid number of operands!");
2724 void addFBits16Operands(MCInst &Inst,
unsigned N)
const {
2725 assert(
N == 1 &&
"Invalid number of operands!");
2730 void addFBits32Operands(MCInst &Inst,
unsigned N)
const {
2731 assert(
N == 1 &&
"Invalid number of operands!");
2736 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
2737 assert(
N == 1 &&
"Invalid number of operands!");
2743 void addImm8s4Operands(MCInst &Inst,
unsigned N)
const {
2744 assert(
N == 1 &&
"Invalid number of operands!");
2751 void addImm7s4Operands(MCInst &Inst,
unsigned N)
const {
2752 assert(
N == 1 &&
"Invalid number of operands!");
2759 void addImm7Shift0Operands(MCInst &Inst,
unsigned N)
const {
2760 assert(
N == 1 &&
"Invalid number of operands!");
2765 void addImm7Shift1Operands(MCInst &Inst,
unsigned N)
const {
2766 assert(
N == 1 &&
"Invalid number of operands!");
2771 void addImm7Shift2Operands(MCInst &Inst,
unsigned N)
const {
2772 assert(
N == 1 &&
"Invalid number of operands!");
2777 void addImm7Operands(MCInst &Inst,
unsigned N)
const {
2778 assert(
N == 1 &&
"Invalid number of operands!");
2783 void addImm0_1020s4Operands(MCInst &Inst,
unsigned N)
const {
2784 assert(
N == 1 &&
"Invalid number of operands!");
2791 void addImm0_508s4NegOperands(MCInst &Inst,
unsigned N)
const {
2792 assert(
N == 1 &&
"Invalid number of operands!");
2799 void addImm0_508s4Operands(MCInst &Inst,
unsigned N)
const {
2800 assert(
N == 1 &&
"Invalid number of operands!");
2807 void addImm1_16Operands(MCInst &Inst,
unsigned N)
const {
2808 assert(
N == 1 &&
"Invalid number of operands!");
2815 void addImm1_32Operands(MCInst &Inst,
unsigned N)
const {
2816 assert(
N == 1 &&
"Invalid number of operands!");
2823 void addImmThumbSROperands(MCInst &Inst,
unsigned N)
const {
2824 assert(
N == 1 &&
"Invalid number of operands!");
2828 unsigned Imm =
CE->getValue();
2832 void addPKHASRImmOperands(MCInst &Inst,
unsigned N)
const {
2833 assert(
N == 1 &&
"Invalid number of operands!");
2837 int Val =
CE->getValue();
2841 void addT2SOImmNotOperands(MCInst &Inst,
unsigned N)
const {
2842 assert(
N == 1 &&
"Invalid number of operands!");
2849 void addT2SOImmNegOperands(MCInst &Inst,
unsigned N)
const {
2850 assert(
N == 1 &&
"Invalid number of operands!");
2857 void addImm0_4095NegOperands(MCInst &Inst,
unsigned N)
const {
2858 assert(
N == 1 &&
"Invalid number of operands!");
2865 void addUnsignedOffset_b8s2Operands(MCInst &Inst,
unsigned N)
const {
2874 void addThumbMemPCOperands(MCInst &Inst,
unsigned N)
const {
2875 assert(
N == 1 &&
"Invalid number of operands!");
2887 assert(isGPRMem() &&
"Unknown value type!");
2895 void addMemBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2896 assert(
N == 1 &&
"Invalid number of operands!");
2900 void addInstSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2901 assert(
N == 1 &&
"Invalid number of operands!");
2905 void addTraceSyncBarrierOptOperands(MCInst &Inst,
unsigned N)
const {
2906 assert(
N == 1 &&
"Invalid number of operands!");
2910 void addMemNoOffsetOperands(MCInst &Inst,
unsigned N)
const {
2911 assert(
N == 1 &&
"Invalid number of operands!");
2915 void addMemNoOffsetT2Operands(MCInst &Inst,
unsigned N)
const {
2916 assert(
N == 1 &&
"Invalid number of operands!");
2920 void addMemNoOffsetT2NoSpOperands(MCInst &Inst,
unsigned N)
const {
2921 assert(
N == 1 &&
"Invalid number of operands!");
2925 void addMemNoOffsetTOperands(MCInst &Inst,
unsigned N)
const {
2926 assert(
N == 1 &&
"Invalid number of operands!");
2930 void addMemPCRelImm12Operands(MCInst &Inst,
unsigned N)
const {
2931 assert(
N == 1 &&
"Invalid number of operands!");
2938 void addAdrLabelOperands(MCInst &Inst,
unsigned N)
const {
2939 assert(
N == 1 &&
"Invalid number of operands!");
2940 assert(isImm() &&
"Not an immediate!");
2950 int Val =
CE->getValue();
2954 void addAlignedMemoryOperands(MCInst &Inst,
unsigned N)
const {
2955 assert(
N == 2 &&
"Invalid number of operands!");
2960 void addDupAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2961 addAlignedMemoryOperands(Inst,
N);
2964 void addAlignedMemoryNoneOperands(MCInst &Inst,
unsigned N)
const {
2965 addAlignedMemoryOperands(Inst,
N);
2968 void addAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2969 addAlignedMemoryOperands(Inst,
N);
2972 void addDupAlignedMemory16Operands(MCInst &Inst,
unsigned N)
const {
2973 addAlignedMemoryOperands(Inst,
N);
2976 void addAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2977 addAlignedMemoryOperands(Inst,
N);
2980 void addDupAlignedMemory32Operands(MCInst &Inst,
unsigned N)
const {
2981 addAlignedMemoryOperands(Inst,
N);
2984 void addAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2985 addAlignedMemoryOperands(Inst,
N);
2988 void addDupAlignedMemory64Operands(MCInst &Inst,
unsigned N)
const {
2989 addAlignedMemoryOperands(Inst,
N);
2992 void addAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2993 addAlignedMemoryOperands(Inst,
N);
2996 void addDupAlignedMemory64or128Operands(MCInst &Inst,
unsigned N)
const {
2997 addAlignedMemoryOperands(Inst,
N);
3000 void addAlignedMemory64or128or256Operands(MCInst &Inst,
unsigned N)
const {
3001 addAlignedMemoryOperands(Inst,
N);
3004 void addAddrMode2Operands(MCInst &Inst,
unsigned N)
const {
3005 assert(
N == 3 &&
"Invalid number of operands!");
3008 if (!Memory.OffsetRegNum) {
3009 if (!Memory.OffsetImm)
3012 int32_t Val =
CE->getValue();
3015 if (Val == std::numeric_limits<int32_t>::min())
3028 Memory.ShiftImm, Memory.ShiftType);
3033 void addAM2OffsetImmOperands(MCInst &Inst,
unsigned N)
const {
3034 assert(
N == 2 &&
"Invalid number of operands!");
3036 assert(CE &&
"non-constant AM2OffsetImm operand!");
3037 int32_t Val =
CE->getValue();
3040 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3041 if (Val < 0) Val = -Val;
3047 void addAddrMode3Operands(MCInst &Inst,
unsigned N)
const {
3048 assert(
N == 3 &&
"Invalid number of operands!");
3061 if (!Memory.OffsetRegNum) {
3062 if (!Memory.OffsetImm)
3065 int32_t Val =
CE->getValue();
3068 if (Val == std::numeric_limits<int32_t>::min())
3085 void addAM3OffsetOperands(MCInst &Inst,
unsigned N)
const {
3086 assert(
N == 2 &&
"Invalid number of operands!");
3087 if (Kind == k_PostIndexRegister) {
3096 const MCConstantExpr *
CE =
static_cast<const MCConstantExpr*
>(
getImm());
3097 int32_t Val =
CE->getValue();
3100 if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
3101 if (Val < 0) Val = -Val;
3107 void addAddrMode5Operands(MCInst &Inst,
unsigned N)
const {
3108 assert(
N == 2 &&
"Invalid number of operands!");
3119 if (!Memory.OffsetImm)
3123 int32_t Val =
CE->getValue() / 4;
3126 if (Val == std::numeric_limits<int32_t>::min())
3136 void addAddrMode5FP16Operands(MCInst &Inst,
unsigned N)
const {
3137 assert(
N == 2 &&
"Invalid number of operands!");
3149 if (!Memory.OffsetImm)
3152 int32_t Val =
CE->getValue() / 2;
3155 if (Val == std::numeric_limits<int32_t>::min())
3165 void addMemImm8s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3166 assert(
N == 2 &&
"Invalid number of operands!");
3177 addExpr(Inst, Memory.OffsetImm);
3180 void addMemImm7s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3181 assert(
N == 2 &&
"Invalid number of operands!");
3192 addExpr(Inst, Memory.OffsetImm);
3195 void addMemImm0_1020s4OffsetOperands(MCInst &Inst,
unsigned N)
const {
3196 assert(
N == 2 &&
"Invalid number of operands!");
3198 if (!Memory.OffsetImm)
3207 void addMemImmOffsetOperands(MCInst &Inst,
unsigned N)
const {
3208 assert(
N == 2 &&
"Invalid number of operands!");
3210 addExpr(Inst, Memory.OffsetImm);
3213 void addMemRegRQOffsetOperands(MCInst &Inst,
unsigned N)
const {
3214 assert(
N == 2 &&
"Invalid number of operands!");
3219 void addMemUImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3220 assert(
N == 2 &&
"Invalid number of operands!");
3230 addExpr(Inst, Memory.OffsetImm);
3233 void addMemImm12OffsetOperands(MCInst &Inst,
unsigned N)
const {
3234 assert(
N == 2 &&
"Invalid number of operands!");
3244 addExpr(Inst, Memory.OffsetImm);
3247 void addConstPoolAsmImmOperands(MCInst &Inst,
unsigned N)
const {
3248 assert(
N == 1 &&
"Invalid number of operands!");
3251 addExpr(Inst, getConstantPoolImm());
3254 void addMemTBBOperands(MCInst &Inst,
unsigned N)
const {
3255 assert(
N == 2 &&
"Invalid number of operands!");
3260 void addMemTBHOperands(MCInst &Inst,
unsigned N)
const {
3261 assert(
N == 2 &&
"Invalid number of operands!");
3266 void addMemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3267 assert(
N == 3 &&
"Invalid number of operands!");
3270 Memory.ShiftImm, Memory.ShiftType);
3276 void addT2MemRegOffsetOperands(MCInst &Inst,
unsigned N)
const {
3277 assert(
N == 3 &&
"Invalid number of operands!");
3283 void addMemThumbRROperands(MCInst &Inst,
unsigned N)
const {
3284 assert(
N == 2 &&
"Invalid number of operands!");
3289 void addMemThumbRIs4Operands(MCInst &Inst,
unsigned N)
const {
3290 assert(
N == 2 &&
"Invalid number of operands!");
3292 if (!Memory.OffsetImm)
3301 void addMemThumbRIs2Operands(MCInst &Inst,
unsigned N)
const {
3302 assert(
N == 2 &&
"Invalid number of operands!");
3304 if (!Memory.OffsetImm)
3312 void addMemThumbRIs1Operands(MCInst &Inst,
unsigned N)
const {
3313 assert(
N == 2 &&
"Invalid number of operands!");
3315 addExpr(Inst, Memory.OffsetImm);
3318 void addMemThumbSPIOperands(MCInst &Inst,
unsigned N)
const {
3319 assert(
N == 2 &&
"Invalid number of operands!");
3321 if (!Memory.OffsetImm)
3330 void addPostIdxImm8Operands(MCInst &Inst,
unsigned N)
const {
3331 assert(
N == 1 &&
"Invalid number of operands!");
3333 assert(CE &&
"non-constant post-idx-imm8 operand!");
3334 int Imm =
CE->getValue();
3335 bool isAdd =
Imm >= 0;
3336 if (
Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3341 void addPostIdxImm8s4Operands(MCInst &Inst,
unsigned N)
const {
3342 assert(
N == 1 &&
"Invalid number of operands!");
3344 assert(CE &&
"non-constant post-idx-imm8s4 operand!");
3345 int Imm =
CE->getValue();
3346 bool isAdd =
Imm >= 0;
3347 if (
Imm == std::numeric_limits<int32_t>::min())
Imm = 0;
3353 void addPostIdxRegOperands(MCInst &Inst,
unsigned N)
const {
3354 assert(
N == 2 &&
"Invalid number of operands!");
3359 void addPostIdxRegShiftedOperands(MCInst &Inst,
unsigned N)
const {
3360 assert(
N == 2 &&
"Invalid number of operands!");
3366 PostIdxReg.ShiftTy);
3370 void addPowerTwoOperands(MCInst &Inst,
unsigned N)
const {
3371 assert(
N == 1 &&
"Invalid number of operands!");
3376 void addMSRMaskOperands(MCInst &Inst,
unsigned N)
const {
3377 assert(
N == 1 &&
"Invalid number of operands!");
3381 void addBankedRegOperands(MCInst &Inst,
unsigned N)
const {
3382 assert(
N == 1 &&
"Invalid number of operands!");
3386 void addProcIFlagsOperands(MCInst &Inst,
unsigned N)
const {
3387 assert(
N == 1 &&
"Invalid number of operands!");
3391 void addVecListOperands(MCInst &Inst,
unsigned N)
const {
3392 assert(
N == 1 &&
"Invalid number of operands!");
3394 if (isAnyVectorList())
3396 else if (isDReg() && !Parser->hasMVE()) {
3398 }
else if (isQReg() && !Parser->hasMVE()) {
3399 MCRegister DPair = Parser->getDRegFromQReg(
Reg.RegNum);
3400 DPair = Parser->getMRI()->getMatchingSuperReg(
3401 DPair, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
3406 "attempted to add a vector list register with wrong type!");
3410 void addMVEVecListOperands(MCInst &Inst,
unsigned N)
const {
3411 assert(
N == 1 &&
"Invalid number of operands!");
3427 const MCRegisterClass *RC_in = &getARMMCRegisterClass(ARM::MQPRRegClassID);
3428 const MCRegisterClass *RC_out =
3429 (VectorList.Count == 2)
3430 ? &getARMMCRegisterClass(ARM::MQQPRRegClassID)
3431 : &getARMMCRegisterClass(ARM::MQQQQPRRegClassID);
3434 for (
I = 0;
I <
E;
I++)
3437 assert(
I <
E &&
"Invalid vector list start register!");
3442 void addVecListIndexedOperands(MCInst &Inst,
unsigned N)
const {
3443 assert(
N == 2 &&
"Invalid number of operands!");
3448 void addVectorIndex8Operands(MCInst &Inst,
unsigned N)
const {
3449 assert(
N == 1 &&
"Invalid number of operands!");
3453 void addVectorIndex16Operands(MCInst &Inst,
unsigned N)
const {
3454 assert(
N == 1 &&
"Invalid number of operands!");
3458 void addVectorIndex32Operands(MCInst &Inst,
unsigned N)
const {
3459 assert(
N == 1 &&
"Invalid number of operands!");
3463 void addVectorIndex64Operands(MCInst &Inst,
unsigned N)
const {
3464 assert(
N == 1 &&
"Invalid number of operands!");
3468 void addMVEVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3469 assert(
N == 1 &&
"Invalid number of operands!");
3473 void addMVEPairVectorIndexOperands(MCInst &Inst,
unsigned N)
const {
3474 assert(
N == 1 &&
"Invalid number of operands!");
3478 void addNEONi8splatOperands(MCInst &Inst,
unsigned N)
const {
3479 assert(
N == 1 &&
"Invalid number of operands!");
3486 void addNEONi16splatOperands(MCInst &Inst,
unsigned N)
const {
3487 assert(
N == 1 &&
"Invalid number of operands!");
3490 unsigned Value =
CE->getValue();
3495 void addNEONi16splatNotOperands(MCInst &Inst,
unsigned N)
const {
3496 assert(
N == 1 &&
"Invalid number of operands!");
3499 unsigned Value =
CE->getValue();
3504 void addNEONi32splatOperands(MCInst &Inst,
unsigned N)
const {
3505 assert(
N == 1 &&
"Invalid number of operands!");
3508 unsigned Value =
CE->getValue();
3513 void addNEONi32splatNotOperands(MCInst &Inst,
unsigned N)
const {
3514 assert(
N == 1 &&
"Invalid number of operands!");
3517 unsigned Value =
CE->getValue();
3522 void addNEONi8ReplicateOperands(MCInst &Inst,
bool Inv)
const {
3527 "All instructions that wants to replicate non-zero byte "
3528 "always must be replaced with VMOVv8i8 or VMOVv16i8.");
3529 unsigned Value =
CE->getValue();
3532 unsigned B =
Value & 0xff;
3537 void addNEONinvi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3538 assert(
N == 1 &&
"Invalid number of operands!");
3539 addNEONi8ReplicateOperands(Inst,
true);
3542 static unsigned encodeNeonVMOVImmediate(
unsigned Value) {
3545 else if (
Value > 0xffff &&
Value <= 0xffffff)
3547 else if (
Value > 0xffffff)
3552 void addNEONi32vmovOperands(MCInst &Inst,
unsigned N)
const {
3553 assert(
N == 1 &&
"Invalid number of operands!");
3556 unsigned Value = encodeNeonVMOVImmediate(
CE->getValue());
3560 void addNEONvmovi8ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3561 assert(
N == 1 &&
"Invalid number of operands!");
3562 addNEONi8ReplicateOperands(Inst,
false);
3565 void addNEONvmovi16ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3566 assert(
N == 1 &&
"Invalid number of operands!");
3572 "All instructions that want to replicate non-zero half-word "
3573 "always must be replaced with V{MOV,MVN}v{4,8}i16.");
3575 unsigned Elem =
Value & 0xffff;
3577 Elem = (Elem >> 8) | 0x200;
3581 void addNEONi32vmovNegOperands(MCInst &Inst,
unsigned N)
const {
3582 assert(
N == 1 &&
"Invalid number of operands!");
3585 unsigned Value = encodeNeonVMOVImmediate(~
CE->getValue());
3589 void addNEONvmovi32ReplicateOperands(MCInst &Inst,
unsigned N)
const {
3590 assert(
N == 1 &&
"Invalid number of operands!");
3596 "All instructions that want to replicate non-zero word "
3597 "always must be replaced with V{MOV,MVN}v{2,4}i32.");
3599 unsigned Elem = encodeNeonVMOVImmediate(
Value & 0xffffffff);
3603 void addNEONi64splatOperands(MCInst &Inst,
unsigned N)
const {
3604 assert(
N == 1 &&
"Invalid number of operands!");
3609 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
3615 void addComplexRotationEvenOperands(MCInst &Inst,
unsigned N)
const {
3616 assert(
N == 1 &&
"Invalid number of operands!");
3621 void addComplexRotationOddOperands(MCInst &Inst,
unsigned N)
const {
3622 assert(
N == 1 &&
"Invalid number of operands!");
3627 void addMveSaturateOperands(MCInst &Inst,
unsigned N)
const {
3628 assert(
N == 1 &&
"Invalid number of operands!");
3630 unsigned Imm =
CE->getValue();
3631 assert((
Imm == 48 ||
Imm == 64) &&
"Invalid saturate operand");
3635 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override;
3637 static std::unique_ptr<ARMOperand> CreateITMask(
unsigned Mask, SMLoc S,
3638 ARMAsmParser &Parser) {
3639 auto Op = std::make_unique<ARMOperand>(k_ITCondMask, Parser);
3646 static std::unique_ptr<ARMOperand>
3648 auto Op = std::make_unique<ARMOperand>(k_CondCode, Parser);
3656 ARMAsmParser &Parser) {
3657 auto Op = std::make_unique<ARMOperand>(k_VPTPred, Parser);
3664 static std::unique_ptr<ARMOperand> CreateCoprocNum(
unsigned CopVal, SMLoc S,
3665 ARMAsmParser &Parser) {
3666 auto Op = std::make_unique<ARMOperand>(k_CoprocNum, Parser);
3667 Op->Cop.Val = CopVal;
3673 static std::unique_ptr<ARMOperand> CreateCoprocReg(
unsigned CopVal, SMLoc S,
3674 ARMAsmParser &Parser) {
3675 auto Op = std::make_unique<ARMOperand>(k_CoprocReg, Parser);
3676 Op->Cop.Val = CopVal;
3682 static std::unique_ptr<ARMOperand>
3683 CreateCoprocOption(
unsigned Val, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3684 auto Op = std::make_unique<ARMOperand>(k_CoprocOption, Parser);
3691 static std::unique_ptr<ARMOperand> CreateCCOut(MCRegister
Reg, SMLoc S,
3692 ARMAsmParser &Parser) {
3693 auto Op = std::make_unique<ARMOperand>(k_CCOut, Parser);
3694 Op->Reg.RegNum =
Reg;
3700 static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S,
3701 ARMAsmParser &Parser) {
3702 auto Op = std::make_unique<ARMOperand>(k_Token, Parser);
3703 Op->Tok.Data = Str.data();
3704 Op->Tok.Length = Str.size();
3710 static std::unique_ptr<ARMOperand> CreateReg(MCRegister
Reg, SMLoc S, SMLoc
E,
3711 ARMAsmParser &Parser) {
3712 auto Op = std::make_unique<ARMOperand>(k_Register, Parser);
3713 Op->Reg.RegNum =
Reg;
3719 static std::unique_ptr<ARMOperand>
3721 MCRegister ShiftReg,
unsigned ShiftImm, SMLoc S,
3722 SMLoc
E, ARMAsmParser &Parser) {
3723 auto Op = std::make_unique<ARMOperand>(k_ShiftedRegister, Parser);
3724 Op->RegShiftedReg.ShiftTy = ShTy;
3725 Op->RegShiftedReg.SrcReg = SrcReg;
3726 Op->RegShiftedReg.ShiftReg = ShiftReg;
3727 Op->RegShiftedReg.ShiftImm = ShiftImm;
3733 static std::unique_ptr<ARMOperand>
3735 unsigned ShiftImm, SMLoc S, SMLoc
E,
3736 ARMAsmParser &Parser) {
3737 auto Op = std::make_unique<ARMOperand>(k_ShiftedImmediate, Parser);
3738 Op->RegShiftedImm.ShiftTy = ShTy;
3739 Op->RegShiftedImm.SrcReg = SrcReg;
3740 Op->RegShiftedImm.ShiftImm = ShiftImm;
3746 static std::unique_ptr<ARMOperand> CreateShifterImm(
bool isASR,
unsigned Imm,
3748 ARMAsmParser &Parser) {
3749 auto Op = std::make_unique<ARMOperand>(k_ShifterImmediate, Parser);
3750 Op->ShifterImm.isASR = isASR;
3751 Op->ShifterImm.Imm =
Imm;
3757 static std::unique_ptr<ARMOperand>
3758 CreateRotImm(
unsigned Imm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3759 auto Op = std::make_unique<ARMOperand>(k_RotateImmediate, Parser);
3760 Op->RotImm.Imm =
Imm;
3766 static std::unique_ptr<ARMOperand> CreateModImm(
unsigned Bits,
unsigned Rot,
3768 ARMAsmParser &Parser) {
3769 auto Op = std::make_unique<ARMOperand>(k_ModifiedImmediate, Parser);
3771 Op->ModImm.Rot = Rot;
3777 static std::unique_ptr<ARMOperand>
3778 CreateConstantPoolImm(
const MCExpr *Val, SMLoc S, SMLoc
E,
3779 ARMAsmParser &Parser) {
3780 auto Op = std::make_unique<ARMOperand>(k_ConstantPoolImmediate, Parser);
3787 static std::unique_ptr<ARMOperand> CreateBitfield(
unsigned LSB,
3788 unsigned Width, SMLoc S,
3790 ARMAsmParser &Parser) {
3791 auto Op = std::make_unique<ARMOperand>(k_BitfieldDescriptor, Parser);
3792 Op->Bitfield.LSB = LSB;
3793 Op->Bitfield.Width = Width;
3799 static std::unique_ptr<ARMOperand>
3800 CreateRegList(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
3801 SMLoc StartLoc, SMLoc EndLoc, ARMAsmParser &Parser) {
3802 assert(Regs.size() > 0 &&
"RegList contains no registers?");
3803 KindTy Kind = k_RegisterList;
3805 if (getARMMCRegisterClass(ARM::DPRRegClassID)
3807 if (Regs.back().second == ARM::VPR)
3808 Kind = k_FPDRegisterListWithVPR;
3810 Kind = k_DPRRegisterList;
3811 }
else if (getARMMCRegisterClass(ARM::SPRRegClassID)
3813 if (Regs.back().second == ARM::VPR)
3814 Kind = k_FPSRegisterListWithVPR;
3816 Kind = k_SPRRegisterList;
3817 }
else if (Regs.front().second == ARM::VPR) {
3818 assert(Regs.size() == 1 &&
3819 "Register list starting with VPR expected to only contain VPR");
3820 Kind = k_FPSRegisterListWithVPR;
3823 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3824 Kind = k_RegisterListWithAPSR;
3828 auto Op = std::make_unique<ARMOperand>(Kind, Parser);
3829 for (
const auto &
P : Regs)
3830 Op->Registers.push_back(
P.second);
3832 Op->StartLoc = StartLoc;
3833 Op->EndLoc = EndLoc;
3837 static std::unique_ptr<ARMOperand>
3838 CreateVectorList(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced, SMLoc S,
3839 SMLoc
E, ARMAsmParser &Parser) {
3840 auto Op = std::make_unique<ARMOperand>(k_VectorList, Parser);
3841 Op->VectorList.RegNum =
Reg;
3843 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3849 static std::unique_ptr<ARMOperand>
3850 CreateVectorListAllLanes(MCRegister
Reg,
unsigned Count,
bool isDoubleSpaced,
3851 SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3852 auto Op = std::make_unique<ARMOperand>(k_VectorListAllLanes, Parser);
3853 Op->VectorList.RegNum =
Reg;
3855 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3861 static std::unique_ptr<ARMOperand>
3862 CreateVectorListIndexed(MCRegister
Reg,
unsigned Count,
unsigned Index,
3863 bool isDoubleSpaced, SMLoc S, SMLoc
E,
3864 ARMAsmParser &Parser) {
3865 auto Op = std::make_unique<ARMOperand>(k_VectorListIndexed, Parser);
3866 Op->VectorList.RegNum =
Reg;
3868 Op->VectorList.LaneIndex =
Index;
3869 Op->VectorList.isDoubleSpaced = isDoubleSpaced;
3875 static std::unique_ptr<ARMOperand> CreateVectorIndex(
unsigned Idx, SMLoc S,
3876 SMLoc
E, MCContext &Ctx,
3877 ARMAsmParser &Parser) {
3878 auto Op = std::make_unique<ARMOperand>(k_VectorIndex, Parser);
3879 Op->VectorIndex.Val =
Idx;
3885 static std::unique_ptr<ARMOperand> CreateImm(
const MCExpr *Val, SMLoc S,
3886 SMLoc
E, ARMAsmParser &Parser) {
3887 auto Op = std::make_unique<ARMOperand>(k_Immediate, Parser);
3894 static std::unique_ptr<ARMOperand>
3895 CreateMem(MCRegister BaseReg,
const MCExpr *OffsetImm, MCRegister OffsetReg,
3897 bool isNegative, SMLoc S, SMLoc
E, ARMAsmParser &Parser,
3898 SMLoc AlignmentLoc = SMLoc()) {
3899 auto Op = std::make_unique<ARMOperand>(k_Memory, Parser);
3901 Op->Memory.OffsetImm = OffsetImm;
3902 Op->Memory.OffsetRegNum = OffsetReg;
3903 Op->Memory.ShiftType = ShiftType;
3904 Op->Memory.ShiftImm = ShiftImm;
3906 Op->Memory.isNegative = isNegative;
3909 Op->AlignmentLoc = AlignmentLoc;
3913 static std::unique_ptr<ARMOperand>
3915 unsigned ShiftImm, SMLoc S, SMLoc
E, ARMAsmParser &Parser) {
3916 auto Op = std::make_unique<ARMOperand>(k_PostIndexRegister, Parser);
3917 Op->PostIdxReg.RegNum =
Reg;
3918 Op->PostIdxReg.isAdd = isAdd;
3919 Op->PostIdxReg.ShiftTy = ShiftTy;
3920 Op->PostIdxReg.ShiftImm = ShiftImm;
3926 static std::unique_ptr<ARMOperand>
3927 CreateMemBarrierOpt(
ARM_MB::MemBOpt Opt, SMLoc S, ARMAsmParser &Parser) {
3928 auto Op = std::make_unique<ARMOperand>(k_MemBarrierOpt, Parser);
3929 Op->MBOpt.Val = Opt;
3935 static std::unique_ptr<ARMOperand>
3937 ARMAsmParser &Parser) {
3938 auto Op = std::make_unique<ARMOperand>(k_InstSyncBarrierOpt, Parser);
3939 Op->ISBOpt.Val = Opt;
3945 static std::unique_ptr<ARMOperand>
3947 ARMAsmParser &Parser) {
3948 auto Op = std::make_unique<ARMOperand>(k_TraceSyncBarrierOpt, Parser);
3949 Op->TSBOpt.Val = Opt;
3955 static std::unique_ptr<ARMOperand>
3957 auto Op = std::make_unique<ARMOperand>(k_ProcIFlags, Parser);
3964 static std::unique_ptr<ARMOperand> CreateMSRMask(
unsigned MMask, SMLoc S,
3965 ARMAsmParser &Parser) {
3966 auto Op = std::make_unique<ARMOperand>(k_MSRMask, Parser);
3967 Op->MMask.Val = MMask;
3973 static std::unique_ptr<ARMOperand> CreateBankedReg(
unsigned Reg, SMLoc S,
3974 ARMAsmParser &Parser) {
3975 auto Op = std::make_unique<ARMOperand>(k_BankedReg, Parser);
3976 Op->BankedReg.Val =
Reg;
3985void ARMOperand::print(raw_ostream &OS,
const MCAsmInfo &MAI)
const {
4003 case k_ITCondMask: {
4004 static const char *
const MaskStr[] = {
4005 "(invalid)",
"(tttt)",
"(ttt)",
"(ttte)",
4006 "(tt)",
"(ttet)",
"(tte)",
"(ttee)",
4007 "(t)",
"(tett)",
"(tet)",
"(tete)",
4008 "(te)",
"(teet)",
"(tee)",
"(teee)",
4010 assert((ITMask.Mask & 0xf) == ITMask.Mask);
4011 OS <<
"<it-mask " << MaskStr[ITMask.Mask] <<
">";
4015 OS <<
"<coprocessor number: " << getCoproc() <<
">";
4018 OS <<
"<coprocessor register: " << getCoproc() <<
">";
4020 case k_CoprocOption:
4021 OS <<
"<coprocessor option: " << CoprocOption.Val <<
">";
4024 OS <<
"<mask: " << getMSRMask() <<
">";
4027 OS <<
"<banked reg: " << getBankedReg() <<
">";
4032 case k_MemBarrierOpt:
4033 OS <<
"<ARM_MB::" << MemBOptToString(getMemBarrierOpt(),
false) <<
">";
4035 case k_InstSyncBarrierOpt:
4036 OS <<
"<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) <<
">";
4038 case k_TraceSyncBarrierOpt:
4039 OS <<
"<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) <<
">";
4043 if (Memory.BaseRegNum)
4044 OS <<
" base:" <<
RegName(Memory.BaseRegNum);
4045 if (Memory.OffsetImm) {
4046 OS <<
" offset-imm:";
4049 if (Memory.OffsetRegNum)
4050 OS <<
" offset-reg:" << (Memory.isNegative ?
"-" :
"")
4051 <<
RegName(Memory.OffsetRegNum);
4054 OS <<
" shift-imm:" << Memory.ShiftImm;
4056 if (Memory.Alignment)
4057 OS <<
" alignment:" << Memory.Alignment;
4060 case k_PostIndexRegister:
4061 OS <<
"post-idx register " << (PostIdxReg.isAdd ?
"" :
"-")
4062 <<
RegName(PostIdxReg.RegNum);
4065 << PostIdxReg.ShiftImm;
4068 case k_ProcIFlags: {
4069 OS <<
"<ARM_PROC::";
4070 unsigned IFlags = getProcIFlags();
4071 for (
int i=2; i >= 0; --i)
4072 if (IFlags & (1 << i))
4080 case k_ShifterImmediate:
4081 OS <<
"<shift " << (ShifterImm.isASR ?
"asr" :
"lsl")
4082 <<
" #" << ShifterImm.Imm <<
">";
4084 case k_ShiftedRegister:
4085 OS <<
"<so_reg_reg " <<
RegName(RegShiftedReg.SrcReg) <<
" "
4087 <<
RegName(RegShiftedReg.ShiftReg) <<
">";
4089 case k_ShiftedImmediate:
4090 OS <<
"<so_reg_imm " <<
RegName(RegShiftedImm.SrcReg) <<
" "
4092 << RegShiftedImm.ShiftImm <<
">";
4094 case k_RotateImmediate:
4095 OS <<
"<ror " <<
" #" << (RotImm.Imm * 8) <<
">";
4097 case k_ModifiedImmediate:
4098 OS <<
"<mod_imm #" << ModImm.Bits <<
", #"
4099 << ModImm.Rot <<
")>";
4101 case k_ConstantPoolImmediate:
4102 OS <<
"<constant_pool_imm #";
4103 MAI.
printExpr(OS, *getConstantPoolImm());
4105 case k_BitfieldDescriptor:
4106 OS <<
"<bitfield " <<
"lsb: " <<
Bitfield.LSB
4107 <<
", width: " <<
Bitfield.Width <<
">";
4109 case k_RegisterList:
4110 case k_RegisterListWithAPSR:
4111 case k_DPRRegisterList:
4112 case k_SPRRegisterList:
4113 case k_FPSRegisterListWithVPR:
4114 case k_FPDRegisterListWithVPR: {
4115 OS <<
"<register_list ";
4117 const SmallVectorImpl<MCRegister> &RegList = getRegList();
4118 for (
auto I = RegList.
begin(),
E = RegList.
end();
I !=
E;) {
4120 if (++
I <
E) OS <<
", ";
4127 OS <<
"<vector_list " << VectorList.Count <<
" * "
4128 <<
RegName(VectorList.RegNum) <<
">";
4130 case k_VectorListAllLanes:
4131 OS <<
"<vector_list(all lanes) " << VectorList.Count <<
" * "
4132 <<
RegName(VectorList.RegNum) <<
">";
4134 case k_VectorListIndexed:
4135 OS <<
"<vector_list(lane " << VectorList.LaneIndex <<
") "
4136 << VectorList.Count <<
" * " <<
RegName(VectorList.RegNum) <<
">";
4142 OS <<
"<vectorindex " << getVectorIndex() <<
">";
4156 ".8",
".16",
".32",
".64",
".i8",
".i16",
".i32",
".i64",
4157 ".u8",
".u16",
".u32",
".u64",
".s8",
".s16",
".s32",
".s64",
4158 ".p8",
".p16",
".f32",
".f64",
".f",
".d"};
4163 unsigned MnemonicOpsEndInd = 1;
4169 static_cast<ARMOperand &
>(*
Operands[1]).getImm()->getKind() ==
4172 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4175 static_cast<ARMOperand &
>(*
Operands[1]).getImm())
4177 ++MnemonicOpsEndInd;
4181 bool RHSCondCode =
false;
4182 while (MnemonicOpsEndInd <
Operands.size()) {
4183 auto Op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
4185 if (
Op.isITMask()) {
4187 MnemonicOpsEndInd++;
4188 }
else if (
Op.isToken() &&
4192 Op.getToken() ==
".w" ||
Op.getToken() ==
".bf16" ||
4193 Op.getToken() ==
".p64" ||
Op.getToken() ==
".f16" ||
4199 MnemonicOpsEndInd++;
4202 else if (
Op.isCCOut() || (
Op.isCondCode() && !RHSCondCode) ||
4203 Op.isVPTPred() || (
Op.isToken() &&
Op.getToken() ==
".w"))
4204 MnemonicOpsEndInd++;
4208 return MnemonicOpsEndInd;
4211bool ARMAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4213 const AsmToken &Tok = getParser().getTok();
4216 Reg = tryParseRegister();
4221ParseStatus ARMAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
4223 if (parseRegister(
Reg, StartLoc, EndLoc))
4231MCRegister ARMAsmParser::tryParseRegister(
bool AllowOutOfBoundReg) {
4232 MCAsmParser &Parser = getParser();
4233 const AsmToken &Tok = Parser.
getTok();
4235 return MCRegister();
4240 Reg = StringSwitch<MCRegister>(lowerCase)
4241 .Case(
"r13", ARM::SP)
4242 .Case(
"r14", ARM::LR)
4243 .Case(
"r15", ARM::PC)
4244 .Case(
"ip", ARM::R12)
4246 .Case(
"a1", ARM::R0)
4247 .Case(
"a2", ARM::R1)
4248 .Case(
"a3", ARM::R2)
4249 .Case(
"a4", ARM::R3)
4250 .Case(
"v1", ARM::R4)
4251 .Case(
"v2", ARM::R5)
4252 .Case(
"v3", ARM::R6)
4253 .Case(
"v4", ARM::R7)
4254 .Case(
"v5", ARM::R8)
4255 .Case(
"v6", ARM::R9)
4256 .Case(
"v7", ARM::R10)
4257 .Case(
"v8", ARM::R11)
4258 .Case(
"sb", ARM::R9)
4259 .Case(
"sl", ARM::R10)
4260 .Case(
"fp", ARM::R11)
4261 .Default(MCRegister());
4267 auto Entry = RegisterReqs.
find(lowerCase);
4269 if (Entry == RegisterReqs.
end())
4270 return MCRegister();
4272 return Entry->getValue();
4276 if (!AllowOutOfBoundReg && !hasD32() &&
Reg >=
ARM::D16 &&
Reg <= ARM::D31)
4277 return MCRegister();
4284std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() {
4285 MCAsmParser &Parser = getParser();
4286 const AsmToken &Tok = Parser.
getTok();
4288 return std::nullopt;
4291 return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase)
4298 .Default(std::nullopt);
4307 MCAsmParser &Parser = getParser();
4310 auto ShiftTyOpt = tryParseShiftToken();
4311 if (ShiftTyOpt == std::nullopt)
4313 auto ShiftTy = ShiftTyOpt.value();
4320 std::unique_ptr<ARMOperand> PrevOp(
4321 (ARMOperand *)
Operands.pop_back_val().release());
4322 if (!PrevOp->isReg())
4323 return Error(PrevOp->getStartLoc(),
"shift must be of a register");
4324 MCRegister SrcReg = PrevOp->getReg();
4328 MCRegister ShiftReg;
4340 const MCExpr *ShiftExpr =
nullptr;
4341 if (getParser().parseExpression(ShiftExpr, EndLoc)) {
4342 Error(ImmLoc,
"invalid immediate shift value");
4348 Error(ImmLoc,
"invalid immediate shift value");
4354 Imm =
CE->getValue();
4358 Error(ImmLoc,
"immediate shift value out of range");
4368 ShiftReg = tryParseRegister();
4370 Error(L,
"expected immediate or register in shift operand");
4375 "expected immediate or register in shift operand");
4381 Operands.push_back(ARMOperand::CreateShiftedRegister(
4382 ShiftTy, SrcReg, ShiftReg,
Imm, S, EndLoc, *
this));
4384 Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg,
Imm,
4397 MCAsmParser &Parser = getParser();
4400 MCRegister
Reg = tryParseRegister();
4404 Operands.push_back(ARMOperand::CreateReg(
Reg, RegStartLoc, RegEndLoc, *
this));
4406 const AsmToken &ExclaimTok = Parser.
getTok();
4409 ExclaimTok.
getLoc(), *
this));
4421 const MCExpr *ImmVal;
4422 if (getParser().parseExpression(ImmVal))
4426 return TokError(
"immediate value expected for vector index");
4453 if (Name.size() < 2 || Name[0] != CoprocOp)
4455 Name = (Name[1] ==
'r') ? Name.drop_front(2) : Name.drop_front();
4457 switch (Name.size()) {
4480 case '0':
return 10;
4481 case '1':
return 11;
4482 case '2':
return 12;
4483 case '3':
return 13;
4484 case '4':
return 14;
4485 case '5':
return 15;
4492 MCAsmParser &Parser = getParser();
4494 const AsmToken &Tok = Parser.
getTok();
4512 MCAsmParser &Parser = getParser();
4514 const AsmToken &Tok = Parser.
getTok();
4525 Operands.push_back(ARMOperand::CreateCoprocNum(Num, S, *
this));
4533 MCAsmParser &Parser = getParser();
4535 const AsmToken &Tok = Parser.
getTok();
4544 Operands.push_back(ARMOperand::CreateCoprocReg(
Reg, S, *
this));
4551 MCAsmParser &Parser = getParser();
4561 if (getParser().parseExpression(Expr))
4562 return Error(Loc,
"illegal expression");
4564 if (!CE ||
CE->getValue() < 0 ||
CE->getValue() > 255)
4566 "coprocessor option must be an immediate in range [0, 255]");
4567 int Val =
CE->getValue();
4575 Operands.push_back(ARMOperand::CreateCoprocOption(Val, S,
E, *
this));
4586 if (!getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4590 case ARM::R0:
return ARM::R1;
case ARM::R1:
return ARM::R2;
4591 case ARM::R2:
return ARM::R3;
case ARM::R3:
return ARM::R4;
4592 case ARM::R4:
return ARM::R5;
case ARM::R5:
return ARM::R6;
4593 case ARM::R6:
return ARM::R7;
case ARM::R7:
return ARM::R8;
4594 case ARM::R8:
return ARM::R9;
case ARM::R9:
return ARM::R10;
4595 case ARM::R10:
return ARM::R11;
case ARM::R11:
return ARM::R12;
4596 case ARM::R12:
return ARM::SP;
case ARM::SP:
return ARM::LR;
4597 case ARM::LR:
return ARM::PC;
case ARM::PC:
return ARM::R0;
4606 Regs.emplace_back(Enc,
Reg);
4607 for (
auto I = Regs.rbegin(), J =
I + 1,
E = Regs.rend(); J !=
E; ++
I, ++J) {
4608 if (J->first == Enc) {
4609 Regs.erase(J.base());
4621 bool AllowRAAC,
bool IsLazyLoadStore,
4623 MCAsmParser &Parser = getParser();
4625 return TokError(
"Token is not a Left Curly Brace");
4632 bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4633 MCRegister
Reg = tryParseRegister(AllowOutOfBoundReg);
4635 return Error(RegLoc,
"register expected");
4636 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4637 return Error(RegLoc,
"pseudo-register not allowed");
4648 bool VSCCLRMAdjustEncoding =
false;
4651 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4652 Reg = getDRegFromQReg(
Reg);
4653 EReg =
MRI->getEncodingValue(
Reg);
4657 const MCRegisterClass *RC;
4658 if (
Reg == ARM::RA_AUTH_CODE ||
4659 getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4660 RC = &getARMMCRegisterClass(ARM::GPRRegClassID);
4661 else if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg))
4662 RC = &getARMMCRegisterClass(ARM::DPRRegClassID);
4663 else if (getARMMCRegisterClass(ARM::SPRRegClassID).
contains(
Reg))
4664 RC = &getARMMCRegisterClass(ARM::SPRRegClassID);
4665 else if (getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg))
4666 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4667 else if (
Reg == ARM::VPR)
4668 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4670 return Error(RegLoc,
"invalid register in register list");
4673 EReg =
MRI->getEncodingValue(
Reg);
4682 if (
Reg == ARM::RA_AUTH_CODE)
4683 return Error(RegLoc,
"pseudo-register not allowed");
4686 MCRegister EndReg = tryParseRegister(AllowOutOfBoundReg);
4688 return Error(AfterMinusLoc,
"register expected");
4689 if (EndReg == ARM::RA_AUTH_CODE)
4690 return Error(AfterMinusLoc,
"pseudo-register not allowed");
4692 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4693 EndReg = getDRegFromQReg(EndReg) + 1;
4700 return Error(AfterMinusLoc,
"invalid register in register list");
4702 if (
MRI->getEncodingValue(
Reg) >
MRI->getEncodingValue(EndReg))
4703 return Error(AfterMinusLoc,
"bad range in register list");
4706 while (
Reg != EndReg) {
4708 EReg =
MRI->getEncodingValue(
Reg);
4709 if (VSCCLRMAdjustEncoding)
4712 Warning(AfterMinusLoc, StringRef(
"duplicated register (") +
4714 ") in register list");
4721 MCRegister OldReg =
Reg;
4723 const AsmToken RegTok = Parser.
getTok();
4724 Reg = tryParseRegister(AllowOutOfBoundReg);
4726 return Error(RegLoc,
"register expected");
4727 if (!AllowRAAC &&
Reg == ARM::RA_AUTH_CODE)
4728 return Error(RegLoc,
"pseudo-register not allowed");
4730 bool isQReg =
false;
4731 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4732 Reg = getDRegFromQReg(
Reg);
4736 RC->
getID() == getARMMCRegisterClass(ARM::GPRRegClassID).getID() &&
4737 getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID).
contains(
Reg)) {
4740 RC = &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID);
4742 if (
Reg == ARM::VPR &&
4743 (RC == &getARMMCRegisterClass(ARM::SPRRegClassID) ||
4744 RC == &getARMMCRegisterClass(ARM::DPRRegClassID) ||
4745 RC == &getARMMCRegisterClass(ARM::FPWithVPRRegClassID))) {
4746 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4747 EReg =
MRI->getEncodingValue(
Reg);
4750 ") in register list");
4756 if (IsVSCCLRM && OldReg == ARM::S31 &&
Reg ==
ARM::D16) {
4757 VSCCLRMAdjustEncoding =
true;
4758 RC = &getARMMCRegisterClass(ARM::FPWithVPRRegClassID);
4761 if ((
Reg == ARM::RA_AUTH_CODE &&
4762 RC != &getARMMCRegisterClass(ARM::GPRRegClassID)) ||
4764 return Error(RegLoc,
"invalid register in register list");
4769 EReg =
MRI->getEncodingValue(
Reg);
4770 if (VSCCLRMAdjustEncoding)
4772 if (EnforceOrder && EReg < EOldReg) {
4773 if (getARMMCRegisterClass(ARM::GPRRegClassID).
contains(
Reg))
4774 Warning(RegLoc,
"register list not in ascending order");
4775 else if (!getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
4777 return Error(RegLoc,
"register list not in ascending order");
4780 if (RC != &getARMMCRegisterClass(ARM::GPRRegClassID) &&
4781 RC != &getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID) &&
4782 EReg != EOldReg + 1)
4783 return Error(RegLoc,
"non-contiguous register range");
4787 ") in register list");
4791 EReg =
MRI->getEncodingValue(
Reg);
4807 ARMOperand::CreateToken(
"^", Parser.
getTok().
getLoc(), *
this));
4815ParseStatus ARMAsmParser::parseVectorLane(VectorLaneTy &LaneKind,
4816 unsigned &Index, SMLoc &EndLoc) {
4817 MCAsmParser &Parser = getParser();
4823 LaneKind = AllLanes;
4834 const MCExpr *LaneIndex;
4836 if (getParser().parseExpression(LaneIndex))
4837 return Error(Loc,
"illegal expression");
4840 return Error(Loc,
"lane index must be empty or an integer");
4845 int64_t Val =
CE->getValue();
4848 if (Val < 0 || Val > 7)
4851 LaneKind = IndexedLane;
4860 MCAsmParser &Parser = getParser();
4861 VectorLaneTy LaneKind;
4871 MCRegister
Reg = tryParseRegister();
4874 if (getARMMCRegisterClass(ARM::DPRRegClassID).
contains(
Reg)) {
4875 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4880 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4884 ARMOperand::CreateVectorListAllLanes(
Reg, 1,
false, S,
E, *
this));
4887 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4888 Reg, 1, LaneIndex,
false, S,
E, *
this));
4893 if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
4894 Reg = getDRegFromQReg(
Reg);
4895 ParseStatus Res = parseVectorLane(LaneKind, LaneIndex,
E);
4900 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4903 Reg =
MRI->getMatchingSuperReg(
4904 Reg, ARM::dsub_0, &getARMMCRegisterClass(ARM::DPairRegClassID));
4906 ARMOperand::CreateVectorListAllLanes(
Reg, 2,
false, S,
E, *
this));
4909 Operands.push_back(ARMOperand::CreateVectorListIndexed(
4910 Reg, 2, LaneIndex,
false, S,
E, *
this));
4915 Operands.push_back(ARMOperand::CreateReg(
Reg, S,
E, *
this));
4925 MCRegister
Reg = tryParseRegister();
4927 return Error(RegLoc,
"register expected");
4930 MCRegister FirstReg =
Reg;
4932 if (hasMVE() && !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
4934 "vector register in range Q0-Q7 expected");
4937 else if (!hasMVE() &&
4938 getARMMCRegisterClass(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");
4965 getARMMCRegisterClass(ARM::QPRRegClassID).
contains(EndReg))
4966 EndReg = getDRegFromQReg(EndReg) + 1;
4973 !getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(EndReg)) ||
4975 !getARMMCRegisterClass(ARM::DPRRegClassID).
contains(EndReg)))
4976 return Error(AfterMinusLoc,
"invalid register in register list");
4979 return Error(AfterMinusLoc,
"bad range in register list");
4981 VectorLaneTy NextLaneKind;
4982 unsigned NextLaneIndex;
4983 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
4985 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
4986 return Error(AfterMinusLoc,
"mismatched lane index in register list");
4995 MCRegister OldReg =
Reg;
4996 Reg = tryParseRegister();
4998 return Error(RegLoc,
"register expected");
5001 if (!getARMMCRegisterClass(ARM::MQPRRegClassID).
contains(
Reg))
5002 return Error(RegLoc,
"vector register in range Q0-Q7 expected");
5011 else if (getARMMCRegisterClass(ARM::QPRRegClassID).
contains(
Reg)) {
5014 else if (Spacing == 2)
5017 "invalid register in double-spaced list (must be 'D' register')");
5018 Reg = getDRegFromQReg(
Reg);
5019 if (
Reg != OldReg + 1)
5020 return Error(RegLoc,
"non-contiguous register range");
5024 VectorLaneTy NextLaneKind;
5025 unsigned NextLaneIndex;
5027 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5029 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5030 return Error(LaneLoc,
"mismatched lane index in register list");
5037 Spacing = 1 + (
Reg == OldReg + 2);
5040 if (
Reg != OldReg + Spacing)
5041 return Error(RegLoc,
"non-contiguous register range");
5044 VectorLaneTy NextLaneKind;
5045 unsigned NextLaneIndex;
5047 if (!parseVectorLane(NextLaneKind, NextLaneIndex,
E).isSuccess())
5049 if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex)
5050 return Error(EndLoc,
"mismatched lane index in register list");
5063 if (
Count == 2 && !hasMVE()) {
5064 const MCRegisterClass *RC =
5065 (Spacing == 1) ? &getARMMCRegisterClass(ARM::DPairRegClassID)
5066 : &getARMMCRegisterClass(ARM::DPairSpcRegClassID);
5067 FirstReg =
MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
5069 auto Create = (LaneKind == NoLanes ? ARMOperand::CreateVectorList :
5070 ARMOperand::CreateVectorListAllLanes);
5071 Operands.push_back(Create(FirstReg,
Count, (Spacing == 2), S,
E, *
this));
5075 Operands.push_back(ARMOperand::CreateVectorListIndexed(
5076 FirstReg,
Count, LaneIndex, (Spacing == 2), S,
E, *
this));
5084 MCAsmParser &Parser = getParser();
5086 const AsmToken &Tok = Parser.
getTok();
5092 Opt = StringSwitch<unsigned>(OptStr.
lower())
5127 const MCExpr *MemBarrierID;
5128 if (getParser().parseExpression(MemBarrierID))
5129 return Error(Loc,
"illegal expression");
5133 return Error(Loc,
"constant expression expected");
5135 int Val =
CE->getValue();
5137 return Error(Loc,
"immediate value out of range");
5142 "expected an immediate or barrier type");
5151 MCAsmParser &Parser = getParser();
5153 const AsmToken &Tok = Parser.
getTok();
5164 ARMOperand::CreateTraceSyncBarrierOpt(
ARM_TSB::CSYNC, S, *
this));
5171 MCAsmParser &Parser = getParser();
5173 const AsmToken &Tok = Parser.
getTok();
5192 const MCExpr *ISBarrierID;
5193 if (getParser().parseExpression(ISBarrierID))
5194 return Error(Loc,
"illegal expression");
5198 return Error(Loc,
"constant expression expected");
5200 int Val =
CE->getValue();
5202 return Error(Loc,
"immediate value out of range");
5207 "expected an immediate or barrier type");
5209 Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
5216 MCAsmParser &Parser = getParser();
5218 const AsmToken &Tok = Parser.
getTok();
5226 if (IFlagsStr !=
"none") {
5227 for (
int i = 0, e = IFlagsStr.
size(); i != e; ++i) {
5228 unsigned Flag = StringSwitch<unsigned>(IFlagsStr.
substr(i, 1).
lower())
5236 if (Flag == ~0U || (IFlags & Flag))
5252 if (
static_cast<ARMOperand &
>(*
Operands.back()).isMSRMask() ||
5253 static_cast<ARMOperand &
>(*
Operands.back()).isBankedReg())
5255 MCAsmParser &Parser = getParser();
5257 const AsmToken &Tok = Parser.
getTok();
5261 if (Val > 255 || Val < 0) {
5264 unsigned SYSmvalue = Val & 0xFF;
5266 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5275 auto TheReg = ARMSysReg::lookupMClassSysRegByName(
Mask.lower());
5276 if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
5279 unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
5282 Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S, *
this));
5288 StringRef
Flags =
"";
5289 std::string SpecReg =
Mask.slice(Start,
Next).lower();
5296 unsigned FlagsVal = 0;
5298 if (SpecReg ==
"apsr") {
5299 FlagsVal = StringSwitch<unsigned>(Flags)
5302 .Case(
"nzcvqg", 0xc)
5305 if (FlagsVal == ~0U) {
5311 }
else if (SpecReg ==
"cpsr" || SpecReg ==
"spsr") {
5313 if (Flags ==
"all" || Flags ==
"")
5315 for (
int i = 0, e =
Flags.size(); i != e; ++i) {
5316 unsigned Flag = StringSwitch<unsigned>(
Flags.substr(i, 1))
5325 if (Flag == ~0U || (FlagsVal & Flag))
5341 if (SpecReg ==
"spsr")
5345 Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S, *
this));
5353 if (
static_cast<ARMOperand &
>(*
Operands.back()).isBankedReg() ||
5354 static_cast<ARMOperand &
>(*
Operands.back()).isMSRMask())
5356 MCAsmParser &Parser = getParser();
5358 const AsmToken &Tok = Parser.
getTok();
5363 auto TheReg = ARMBankedReg::lookupBankedRegByName(
RegName.lower());
5366 unsigned Encoding = TheReg->Encoding;
5369 Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S, *
this));
5378 MCAsmParser &Parser = getParser();
5379 auto ShiftCodeOpt = tryParseShiftToken();
5381 if (!ShiftCodeOpt.has_value())
5383 auto ShiftCode = ShiftCodeOpt.value();
5387 if (ShiftCode !=
Op)
5399 const MCExpr *ShiftAmount;
5402 if (getParser().parseExpression(ShiftAmount, EndLoc))
5403 return Error(Loc,
"illegal expression");
5406 return Error(Loc,
"constant expression expected");
5407 int Val =
CE->getValue();
5408 if (Val < Low || Val >
High)
5409 return Error(Loc,
"immediate value out of range");
5411 Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc, *
this));
5417 MCAsmParser &Parser = getParser();
5418 const AsmToken &Tok = Parser.
getTok();
5421 return Error(S,
"'be' or 'le' operand expected");
5429 return Error(S,
"'be' or 'le' operand expected");
5430 Operands.push_back(ARMOperand::CreateImm(
5441 MCAsmParser &Parser = getParser();
5442 const AsmToken &Tok = Parser.
getTok();
5448 if (ShiftName ==
"lsl" || ShiftName ==
"LSL")
5450 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
5463 const MCExpr *ShiftAmount;
5465 if (getParser().parseExpression(ShiftAmount, EndLoc))
5466 return Error(ExLoc,
"malformed shift expression");
5469 return Error(ExLoc,
"shift amount must be an immediate");
5471 int64_t Val =
CE->getValue();
5474 if (Val < 1 || Val > 32)
5475 return Error(ExLoc,
"'asr' shift amount must be in range [1,32]");
5478 return Error(ExLoc,
"'asr #32' shift amount not allowed in Thumb mode");
5479 if (Val == 32) Val = 0;
5482 if (Val < 0 || Val > 31)
5483 return Error(ExLoc,
"'lsr' shift amount must be in range [0,31]");
5487 ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc, *
this));
5496 MCAsmParser &Parser = getParser();
5497 const AsmToken &Tok = Parser.
getTok();
5502 if (ShiftName !=
"ror" && ShiftName !=
"ROR")
5513 const MCExpr *ShiftAmount;
5515 if (getParser().parseExpression(ShiftAmount, EndLoc))
5516 return Error(ExLoc,
"malformed rotate expression");
5519 return Error(ExLoc,
"rotate amount must be an immediate");
5521 int64_t Val =
CE->getValue();
5525 if (Val != 8 && Val != 16 && Val != 24 && Val != 0)
5526 return Error(ExLoc,
"'ror' rotate amount must be 8, 16, or 24");
5528 Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc, *
this));
5534 MCAsmParser &Parser = getParser();
5535 AsmLexer &Lexer = getLexer();
5566 const MCExpr *Imm1Exp;
5567 if (getParser().parseExpression(Imm1Exp, Ex1))
5568 return Error(Sx1,
"malformed expression");
5574 Imm1 =
CE->getValue();
5578 Operands.push_back(ARMOperand::CreateModImm(
5579 (Enc & 0xFF), (Enc & 0xF00) >> 7, Sx1, Ex1, *
this));
5590 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5596 Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1, *
this));
5603 "expected modified immediate operand: #[0, 255], #even[0-30]");
5606 return Error(Sx1,
"immediate operand must a number in the range [0, 255]");
5620 const MCExpr *Imm2Exp;
5621 if (getParser().parseExpression(Imm2Exp, Ex2))
5622 return Error(Sx2,
"malformed expression");
5627 Imm2 =
CE->getValue();
5628 if (!(Imm2 & ~0x1E)) {
5630 Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2, *
this));
5634 "immediate operand must an even number in the range [0, 30]");
5636 return Error(Sx2,
"constant expression expected");
5641 MCAsmParser &Parser = getParser();
5649 const MCExpr *LSBExpr;
5651 if (getParser().parseExpression(LSBExpr))
5652 return Error(
E,
"malformed immediate expression");
5655 return Error(
E,
"'lsb' operand must be an immediate");
5657 int64_t LSB =
CE->getValue();
5659 if (LSB < 0 || LSB > 31)
5660 return Error(
E,
"'lsb' operand must be in the range [0,31]");
5672 const MCExpr *WidthExpr;
5674 if (getParser().parseExpression(WidthExpr, EndLoc))
5675 return Error(
E,
"malformed immediate expression");
5678 return Error(
E,
"'width' operand must be an immediate");
5680 int64_t Width =
CE->getValue();
5682 if (Width < 1 || Width > 32 - LSB)
5683 return Error(
E,
"'width' operand must be in the range [1,32-lsb]");
5685 Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc, *
this));
5699 MCAsmParser &Parser = getParser();
5700 AsmToken Tok = Parser.
getTok();
5702 bool haveEaten =
false;
5714 MCRegister
Reg = tryParseRegister();
5722 unsigned ShiftImm = 0;
5725 if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
5733 ARMOperand::CreatePostIdxReg(
Reg, isAdd, ShiftTy, ShiftImm, S,
E, *
this));
5750 MCAsmParser &Parser = getParser();
5751 AsmToken Tok = Parser.
getTok();
5763 if (getParser().parseExpression(
Offset,
E))
5767 return Error(S,
"constant expression expected");
5770 int32_t Val =
CE->getValue();
5771 if (isNegative && Val == 0)
5772 Val = std::numeric_limits<int32_t>::min();
5774 Operands.push_back(ARMOperand::CreateImm(
5780 bool haveEaten =
false;
5792 MCRegister
Reg = tryParseRegister();
5799 Operands.push_back(ARMOperand::CreatePostIdxReg(
5807 unsigned MnemonicOpsEndInd) {
5808 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5809 auto Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
5810 if (
Op.isCondCode())
5817 unsigned MnemonicOpsEndInd) {
5818 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
5819 auto Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
5829void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
5836 unsigned RegRd = MnemonicOpsEndInd;
5837 unsigned RegRn = MnemonicOpsEndInd + 1;
5838 unsigned RegRm = MnemonicOpsEndInd;
5840 if (
Operands.size() == MnemonicOpsEndInd + 3) {
5845 RegRn = MnemonicOpsEndInd + 2;
5846 RegRm = MnemonicOpsEndInd + 1;
5848 RegRn = MnemonicOpsEndInd + 1;
5849 RegRm = MnemonicOpsEndInd + 2;
5854 ((ARMOperand &)*
Operands[RegRd]).addRegOperands(Inst, 1);
5856 if (CondOutI != 0) {
5857 ((ARMOperand &)*
Operands[CondOutI]).addCCOutOperands(Inst, 1);
5860 *ARMOperand::CreateCCOut(0,
Operands[0]->getEndLoc(), *
this);
5861 Op.addCCOutOperands(Inst, 1);
5864 ((ARMOperand &)*
Operands[RegRn]).addRegOperands(Inst, 1);
5866 ((ARMOperand &)*
Operands[RegRm]).addRegOperands(Inst, 1);
5870 ((ARMOperand &)*
Operands[CondI]).addCondCodeOperands(Inst, 2);
5872 ARMOperand
Op = *ARMOperand::CreateCondCode(
5874 Op.addCondCodeOperands(Inst, 2);
5878void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
5884 :
static_cast<ARMOperand &
>(*
Operands[CondI]).getCondCode());
5892 case ARM::tBcc: Inst.
setOpcode(ARM::tB);
break;
5893 case ARM::t2Bcc: Inst.
setOpcode(ARM::t2B);
break;
5912 ARMOperand &
op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
5913 if (!
op.isSignedOffset<11, 1>() &&
isThumb() && hasV8MBaseline())
5919 ARMOperand &
op =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
5920 if (!
op.isSignedOffset<8, 1>() &&
isThumb() && hasV8MBaseline())
5925 ((ARMOperand &)*
Operands[MnemonicOpsEndInd]).addImmOperands(Inst, 1);
5927 ((ARMOperand &)*
Operands[CondI]).addCondCodeOperands(Inst, 2);
5929 ARMOperand
Op = *ARMOperand::CreateCondCode(
5931 Op.addCondCodeOperands(Inst, 2);
5935void ARMAsmParser::cvtMVEVMOVQtoDReg(
5944 ((ARMOperand &)*
Operands[MnemonicOpsEndInd]).addRegOperands(Inst, 1);
5945 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 1])
5946 .addRegOperands(Inst, 1);
5947 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 2])
5948 .addRegOperands(Inst, 1);
5949 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 3])
5950 .addMVEPairVectorIndexOperands(Inst, 1);
5952 ((ARMOperand &)*
Operands[MnemonicOpsEndInd + 5])
5953 .addMVEPairVectorIndexOperands(Inst, 1);
5956 .addCondCodeOperands(Inst, 2);
5960 Op.addCondCodeOperands(Inst, 2);
5967 MCAsmParser &Parser = getParser();
5970 return TokError(
"Token is not a Left Bracket");
5974 const AsmToken &BaseRegTok = Parser.
getTok();
5975 MCRegister
BaseReg = tryParseRegister();
5977 return Error(BaseRegTok.
getLoc(),
"register expected");
5980 const AsmToken &Tok = Parser.
getTok();
5983 return Error(Tok.
getLoc(),
"malformed memory operand");
5989 Operands.push_back(ARMOperand::CreateMem(
5996 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6004 "Lost colon or comma in memory operand?!");
6013 SMLoc AlignmentLoc = Tok.
getLoc();
6016 if (getParser().parseExpression(Expr))
6024 return Error (
E,
"constant expression expected");
6027 switch (
CE->getValue()) {
6030 "alignment specifier must be 16, 32, 64, 128, or 256 bits");
6031 case 16:
Align = 2;
break;
6032 case 32:
Align = 4;
break;
6033 case 64:
Align = 8;
break;
6034 case 128:
Align = 16;
break;
6035 case 256:
Align = 32;
break;
6046 Operands.push_back(ARMOperand::CreateMem(BaseReg,
nullptr, 0,
6048 S,
E, *
this, AlignmentLoc));
6054 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6074 const MCExpr *
Offset, *AdjustedOffset;
6075 if (getParser().parseExpression(
Offset))
6081 int32_t Val =
CE->getValue();
6082 if (isNegative && Val == 0)
6087 AdjustedOffset =
CE;
6090 Operands.push_back(ARMOperand::CreateMem(BaseReg, AdjustedOffset, 0,
6104 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6112 bool isNegative =
false;
6122 MCRegister OffsetReg = tryParseRegister();
6124 return Error(
E,
"register expected");
6128 unsigned ShiftImm = 0;
6131 if (parseMemRegOffsetShift(ShiftType, ShiftImm))
6141 Operands.push_back(ARMOperand::CreateMem(BaseReg,
nullptr, OffsetReg,
6142 ShiftType, ShiftImm, 0, isNegative,
6149 ARMOperand::CreateToken(
"!", Parser.
getTok().
getLoc(), *
this));
6162 MCAsmParser &Parser = getParser();
6164 const AsmToken &Tok = Parser.
getTok();
6166 return Error(Loc,
"illegal shift operator");
6168 if (ShiftName ==
"lsl" || ShiftName ==
"LSL" ||
6169 ShiftName ==
"asl" || ShiftName ==
"ASL")
6171 else if (ShiftName ==
"lsr" || ShiftName ==
"LSR")
6173 else if (ShiftName ==
"asr" || ShiftName ==
"ASR")
6175 else if (ShiftName ==
"ror" || ShiftName ==
"ROR")
6177 else if (ShiftName ==
"rrx" || ShiftName ==
"RRX")
6179 else if (ShiftName ==
"uxtw" || ShiftName ==
"UXTW")
6182 return Error(Loc,
"illegal shift operator");
6190 const AsmToken &HashTok = Parser.
getTok();
6197 if (getParser().parseExpression(Expr))
6204 return Error(Loc,
"shift amount must be an immediate");
6205 int64_t
Imm =
CE->getValue();
6209 return Error(Loc,
"immediate shift value out of range");
6226 MCAsmParser &Parser = getParser();
6253 bool isVmovf =
false;
6255 for (
unsigned I = 1;
I < MnemonicOpsEndInd; ++
I) {
6256 ARMOperand &TyOp =
static_cast<ARMOperand &
>(*
Operands[
I]);
6257 if (TyOp.isToken() &&
6258 (TyOp.getToken() ==
".f32" || TyOp.getToken() ==
".f64" ||
6259 TyOp.getToken() ==
".f16")) {
6265 ARMOperand &Mnemonic =
static_cast<ARMOperand &
>(*
Operands[0]);
6266 bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() ==
"fconstd" ||
6267 Mnemonic.getToken() ==
"fconsts");
6268 if (!(isVmovf || isFconst))
6274 bool isNegative =
false;
6279 const AsmToken &Tok = Parser.
getTok();
6280 SMLoc Loc = Tok.
getLoc();
6297 if (Val > 255 || Val < 0)
6298 return Error(Loc,
"encoded floating point value out of range");
6300 Val =
APFloat(RealVal).bitcastToAPInt().getZExtValue();
6308 return Error(Loc,
"invalid floating point immediate");
6314 MCAsmParser &Parser = getParser();
6319 ParseStatus ResTy = MatchOperandParserImpl(
Operands, Mnemonic);
6328 switch (getLexer().getKind()) {
6336 bool ExpectLabel = Mnemonic ==
"b" || Mnemonic ==
"bl";
6338 if (!tryParseRegisterWithWriteBack(
Operands))
6340 int Res = tryParseShiftRegister(
Operands);
6346 if (Mnemonic ==
"vmrs" &&
6350 Operands.push_back(ARMOperand::CreateToken(
"APSR_nzcv", S, *
this));
6365 const MCExpr *IdVal;
6367 if (getParser().parseExpression(IdVal))
6370 Operands.push_back(ARMOperand::CreateImm(IdVal, S,
E, *
this));
6376 bool IsLazyLoadStore = Mnemonic ==
"vlldm" || Mnemonic ==
"vlstm";
6377 bool IsVSCCLRM = Mnemonic ==
"vscclrm";
6379 IsLazyLoadStore, IsVSCCLRM);
6392 auto AdjacentToken = getLexer().peekTok(
false);
6396 if (!ExpectIdentifier) {
6404 const MCExpr *ImmVal;
6405 if (getParser().parseExpression(ImmVal))
6409 int32_t Val =
CE->getValue();
6410 if (IsNegative && Val == 0)
6415 Operands.push_back(ARMOperand::CreateImm(ImmVal, S,
E, *
this));
6421 Operands.push_back(ARMOperand::CreateToken(
6437 if (parsePrefix(Spec))
6440 const MCExpr *SubExprVal;
6441 if (getParser().parseExpression(SubExprVal))
6444 const auto *ExprVal =
6447 Operands.push_back(ARMOperand::CreateImm(ExprVal, S,
E, *
this));
6452 if (Mnemonic !=
"ldr")
6453 return Error(S,
"unexpected token in operand");
6455 const MCExpr *SubExprVal;
6456 if (getParser().parseExpression(SubExprVal))
6463 ARMOperand::CreateConstantPoolImm(SubExprVal, S,
E, *
this));
6469bool ARMAsmParser::parseImmExpr(int64_t &Out) {
6470 const MCExpr *Expr =
nullptr;
6471 SMLoc
L = getParser().getTok().getLoc();
6472 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
6475 if (check(!
Value, L,
"expected constant expression"))
6485 MCAsmParser &Parser = getParser();
6506 static const struct PrefixEntry {
6507 const char *Spelling;
6509 uint8_t SupportedFormats;
6510 } PrefixEntries[] = {
6522 llvm::find_if(PrefixEntries, [&IDVal](
const PrefixEntry &PE) {
6523 return PE.Spelling == IDVal;
6525 if (Prefix == std::end(PrefixEntries)) {
6530 uint8_t CurrentFormat;
6533 CurrentFormat = MACHO;
6536 CurrentFormat =
ELF;
6539 CurrentFormat =
COFF;
6542 CurrentFormat = WASM;
6552 if (~
Prefix->SupportedFormats & CurrentFormat) {
6554 "cannot represent relocation in the current file format");
6578StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, StringRef ExtraToken,
6582 unsigned &ProcessorIMod,
6583 StringRef &ITMask) {
6586 CarrySetting =
false;
6592 if ((Mnemonic ==
"movs" &&
isThumb()) || Mnemonic ==
"teq" ||
6593 Mnemonic ==
"vceq" || Mnemonic ==
"svc" || Mnemonic ==
"mls" ||
6594 Mnemonic ==
"smmls" || Mnemonic ==
"vcls" || Mnemonic ==
"vmls" ||
6595 Mnemonic ==
"vnmls" || Mnemonic ==
"vacge" || Mnemonic ==
"vcge" ||
6596 Mnemonic ==
"vclt" || Mnemonic ==
"vacgt" || Mnemonic ==
"vaclt" ||
6597 Mnemonic ==
"vacle" || Mnemonic ==
"hlt" || Mnemonic ==
"vcgt" ||
6598 Mnemonic ==
"vcle" || Mnemonic ==
"smlal" || Mnemonic ==
"umaal" ||
6599 Mnemonic ==
"umlal" || Mnemonic ==
"vabal" || Mnemonic ==
"vmlal" ||
6600 Mnemonic ==
"vpadal" || Mnemonic ==
"vqdmlal" || Mnemonic ==
"fmuls" ||
6601 Mnemonic ==
"vmaxnm" || Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" ||
6602 Mnemonic ==
"vcvtn" || Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" ||
6603 Mnemonic ==
"vrinta" || Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" ||
6604 Mnemonic ==
"vrintm" || Mnemonic ==
"hvc" ||
6605 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vins" ||
6606 Mnemonic ==
"vmovx" || Mnemonic ==
"bxns" || Mnemonic ==
"blxns" ||
6607 Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" || Mnemonic ==
"vudot" ||
6608 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6609 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"wls" ||
6610 Mnemonic ==
"le" || Mnemonic ==
"dls" || Mnemonic ==
"csel" ||
6611 Mnemonic ==
"csinc" || Mnemonic ==
"csinv" || Mnemonic ==
"csneg" ||
6612 Mnemonic ==
"cinc" || Mnemonic ==
"cinv" || Mnemonic ==
"cneg" ||
6613 Mnemonic ==
"cset" || Mnemonic ==
"csetm" || Mnemonic ==
"aut" ||
6614 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"bti")
6619 if (Mnemonic !=
"adcs" && Mnemonic !=
"bics" && Mnemonic !=
"movs" &&
6620 Mnemonic !=
"muls" && Mnemonic !=
"smlals" && Mnemonic !=
"smulls" &&
6621 Mnemonic !=
"umlals" && Mnemonic !=
"umulls" && Mnemonic !=
"lsls" &&
6622 Mnemonic !=
"sbcs" && Mnemonic !=
"rscs" &&
6624 (Mnemonic ==
"vmine" || Mnemonic ==
"vshle" || Mnemonic ==
"vshlt" ||
6625 Mnemonic ==
"vshllt" || Mnemonic ==
"vrshle" || Mnemonic ==
"vrshlt" ||
6626 Mnemonic ==
"vmvne" || Mnemonic ==
"vorne" || Mnemonic ==
"vnege" ||
6627 Mnemonic ==
"vnegt" || Mnemonic ==
"vmule" || Mnemonic ==
"vmult" ||
6628 Mnemonic ==
"vrintne" || Mnemonic ==
"vcmult" ||
6629 Mnemonic ==
"vcmule" || Mnemonic ==
"vpsele" || Mnemonic ==
"vpselt" ||
6633 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 2);
6641 !(Mnemonic ==
"cps" || Mnemonic ==
"mls" || Mnemonic ==
"mrs" ||
6642 Mnemonic ==
"smmls" || Mnemonic ==
"vabs" || Mnemonic ==
"vcls" ||
6643 Mnemonic ==
"vmls" || Mnemonic ==
"vmrs" || Mnemonic ==
"vnmls" ||
6644 Mnemonic ==
"vqabs" || Mnemonic ==
"vrecps" || Mnemonic ==
"vrsqrts" ||
6645 Mnemonic ==
"srs" || Mnemonic ==
"flds" || Mnemonic ==
"fmrs" ||
6646 Mnemonic ==
"fsqrts" || Mnemonic ==
"fsubs" || Mnemonic ==
"fsts" ||
6647 Mnemonic ==
"fcpys" || Mnemonic ==
"fdivs" || Mnemonic ==
"fmuls" ||
6648 Mnemonic ==
"fcmps" || Mnemonic ==
"fcmpzs" || Mnemonic ==
"vfms" ||
6649 Mnemonic ==
"vfnms" || Mnemonic ==
"fconsts" || Mnemonic ==
"bxns" ||
6650 Mnemonic ==
"blxns" || Mnemonic ==
"vfmas" || Mnemonic ==
"vmlas" ||
6651 (Mnemonic ==
"movs" &&
isThumb()))) {
6652 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size() - 1);
6653 CarrySetting =
true;
6661 StringSwitch<unsigned>(Mnemonic.
substr(Mnemonic.
size()-2, 2))
6666 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-2);
6667 ProcessorIMod =
IMod;
6671 if (isMnemonicVPTPredicable(Mnemonic, ExtraToken) && Mnemonic !=
"vmovlt" &&
6672 Mnemonic !=
"vshllt" && Mnemonic !=
"vrshrnt" && Mnemonic !=
"vshrnt" &&
6673 Mnemonic !=
"vqrshrunt" && Mnemonic !=
"vqshrunt" &&
6674 Mnemonic !=
"vqrshrnt" && Mnemonic !=
"vqshrnt" && Mnemonic !=
"vmullt" &&
6675 Mnemonic !=
"vqmovnt" && Mnemonic !=
"vqmovunt" && Mnemonic !=
"vmovnt" &&
6676 Mnemonic !=
"vqdmullt" && Mnemonic !=
"vpnot" && Mnemonic !=
"vcvtt" &&
6677 Mnemonic !=
"vcvt") {
6681 Mnemonic = Mnemonic.
slice(0, Mnemonic.
size()-1);
6689 ITMask = Mnemonic.
substr(2);
6690 Mnemonic = Mnemonic.
slice(0, 2);
6694 ITMask = Mnemonic.
substr(4);
6695 Mnemonic = Mnemonic.
slice(0, 4);
6697 ITMask = Mnemonic.
substr(3);
6698 Mnemonic = Mnemonic.
slice(0, 3);
6708void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
6709 StringRef ExtraToken,
6711 bool &CanAcceptCarrySet,
6712 bool &CanAcceptPredicationCode,
6713 bool &CanAcceptVPTPredicationCode) {
6714 CanAcceptVPTPredicationCode = isMnemonicVPTPredicable(Mnemonic, ExtraToken);
6717 Mnemonic ==
"and" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6718 Mnemonic ==
"rrx" || Mnemonic ==
"ror" || Mnemonic ==
"sub" ||
6719 Mnemonic ==
"add" || Mnemonic ==
"adc" || Mnemonic ==
"mul" ||
6720 Mnemonic ==
"bic" || Mnemonic ==
"asr" || Mnemonic ==
"orr" ||
6721 Mnemonic ==
"mvn" || Mnemonic ==
"rsb" || Mnemonic ==
"rsc" ||
6722 Mnemonic ==
"orn" || Mnemonic ==
"sbc" || Mnemonic ==
"eor" ||
6723 Mnemonic ==
"neg" || Mnemonic ==
"vfm" || Mnemonic ==
"vfnm" ||
6725 (Mnemonic ==
"smull" || Mnemonic ==
"mov" || Mnemonic ==
"mla" ||
6726 Mnemonic ==
"smlal" || Mnemonic ==
"umlal" || Mnemonic ==
"umull"));
6728 if (Mnemonic ==
"bkpt" || Mnemonic ==
"cbnz" || Mnemonic ==
"setend" ||
6729 Mnemonic ==
"cps" || Mnemonic ==
"it" || Mnemonic ==
"cbz" ||
6730 Mnemonic ==
"trap" || Mnemonic ==
"hlt" || Mnemonic ==
"udf" ||
6732 Mnemonic.
starts_with(
"vsel") || Mnemonic ==
"vmaxnm" ||
6733 Mnemonic ==
"vminnm" || Mnemonic ==
"vcvta" || Mnemonic ==
"vcvtn" ||
6734 Mnemonic ==
"vcvtp" || Mnemonic ==
"vcvtm" || Mnemonic ==
"vrinta" ||
6735 Mnemonic ==
"vrintn" || Mnemonic ==
"vrintp" || Mnemonic ==
"vrintm" ||
6736 Mnemonic.
starts_with(
"aes") || Mnemonic ==
"hvc" ||
6737 Mnemonic ==
"setpan" || Mnemonic.
starts_with(
"sha1") ||
6740 Mnemonic ==
"vmovx" || Mnemonic ==
"vins" || Mnemonic ==
"vudot" ||
6741 Mnemonic ==
"vsdot" || Mnemonic ==
"vcmla" || Mnemonic ==
"vcadd" ||
6742 Mnemonic ==
"vfmal" || Mnemonic ==
"vfmsl" || Mnemonic ==
"vfmat" ||
6743 Mnemonic ==
"vfmab" || Mnemonic ==
"vdot" || Mnemonic ==
"vmmla" ||
6744 Mnemonic ==
"sb" || Mnemonic ==
"ssbb" || Mnemonic ==
"pssbb" ||
6745 Mnemonic ==
"vsmmla" || Mnemonic ==
"vummla" || Mnemonic ==
"vusmmla" ||
6746 Mnemonic ==
"vusdot" || Mnemonic ==
"vsudot" || Mnemonic ==
"bfcsel" ||
6747 Mnemonic ==
"wls" || Mnemonic ==
"dls" || Mnemonic ==
"le" ||
6748 Mnemonic ==
"csel" || Mnemonic ==
"csinc" || Mnemonic ==
"csinv" ||
6749 Mnemonic ==
"csneg" || Mnemonic ==
"cinc" || Mnemonic ==
"cinv" ||
6750 Mnemonic ==
"cneg" || Mnemonic ==
"cset" || Mnemonic ==
"csetm" ||
6751 (hasCDE() && MS.isCDEInstr(Mnemonic) &&
6752 !MS.isITPredicableCDEInstr(Mnemonic)) ||
6754 Mnemonic ==
"pac" || Mnemonic ==
"pacbti" || Mnemonic ==
"aut" ||
6755 Mnemonic ==
"bti" ||
6762 CanAcceptPredicationCode =
false;
6765 CanAcceptPredicationCode =
6766 Mnemonic !=
"cdp2" && Mnemonic !=
"clrex" && Mnemonic !=
"mcr2" &&
6767 Mnemonic !=
"mcrr2" && Mnemonic !=
"mrc2" && Mnemonic !=
"mrrc2" &&
6768 Mnemonic !=
"dmb" && Mnemonic !=
"dfb" && Mnemonic !=
"dsb" &&
6769 Mnemonic !=
"isb" && Mnemonic !=
"pld" && Mnemonic !=
"pli" &&
6770 Mnemonic !=
"pldw" && Mnemonic !=
"ldc2" && Mnemonic !=
"ldc2l" &&
6771 Mnemonic !=
"stc2" && Mnemonic !=
"stc2l" && Mnemonic !=
"tsb" &&
6773 }
else if (isThumbOne()) {
6775 CanAcceptPredicationCode = Mnemonic !=
"movs";
6777 CanAcceptPredicationCode = Mnemonic !=
"nop" && Mnemonic !=
"movs";
6779 CanAcceptPredicationCode =
true;
6783 for (
unsigned I = 0;
I < MnemonicOpsEndInd; ++
I) {
6784 auto &
Op =
static_cast<ARMOperand &
>(*
Operands[
I]);
6785 if (
Op.isToken() &&
Op.getToken() ==
".w")
6795void ARMAsmParser::tryConvertingToTwoOperandForm(
6801 if (
Operands.size() != MnemonicOpsEndInd + 3)
6804 const auto &Op3 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]);
6805 auto &Op4 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
6806 if (!Op3.isReg() || !Op4.isReg())
6809 auto Op3Reg = Op3.getReg();
6810 auto Op4Reg = Op4.getReg();
6816 auto &Op5 =
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 2]);
6818 if (Mnemonic !=
"add")
6820 bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
6821 (Op5.isReg() && Op5.getReg() == ARM::PC);
6822 if (!TryTransform) {
6823 TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
6824 (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
6825 !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
6826 Op5.isImm() && !Op5.isImm0_508s4());
6830 }
else if (!isThumbOne())
6833 if (!(Mnemonic ==
"add" || Mnemonic ==
"sub" || Mnemonic ==
"and" ||
6834 Mnemonic ==
"eor" || Mnemonic ==
"lsl" || Mnemonic ==
"lsr" ||
6835 Mnemonic ==
"asr" || Mnemonic ==
"adc" || Mnemonic ==
"sbc" ||
6836 Mnemonic ==
"ror" || Mnemonic ==
"orr" || Mnemonic ==
"bic"))
6842 bool Transform = Op3Reg == Op4Reg;
6847 const ARMOperand *LastOp = &Op5;
6849 if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
6850 ((Mnemonic ==
"add" && Op4Reg != ARM::SP) ||
6851 Mnemonic ==
"and" || Mnemonic ==
"eor" ||
6852 Mnemonic ==
"adc" || Mnemonic ==
"orr")) {
6863 if (((Mnemonic ==
"add" && CarrySetting) || Mnemonic ==
"sub") &&
6869 if ((Mnemonic ==
"add" || Mnemonic ==
"sub") && LastOp->isImm0_7())
6885 ARMOperand &
Op =
static_cast<ARMOperand &
>(MCOp);
6895bool ARMAsmParser::shouldOmitVectorPredicateOperand(
6897 if (!hasMVE() ||
Operands.size() <= MnemonicOpsEndInd)
6911 if (
static_cast<ARMOperand &
>(*Operand).isVectorIndex() ||
6912 ((*Operand).isReg() && (getARMMCRegisterClass(ARM::SPRRegClassID)
6914 getARMMCRegisterClass(ARM::DPRRegClassID)
6915 .
contains((*Operand).getReg())))) {
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;
6967 ARMOperand &Op2 =
static_cast<ARMOperand &
>(*
Operands[IdX]);
6968 ARMOperand &Op3 =
static_cast<ARMOperand &
>(*
Operands[IdX + 1]);
6972 if (!Op3.isGPRMem())
6976 if (!GPR.contains(Op2.getReg()))
6979 unsigned RtEncoding =
MRI->getEncodingValue(Op2.getReg());
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];
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,
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);
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)) {
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;
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();
7444 unsigned Rt =
MRI->getEncodingValue(Reg1);
7445 MCRegister Reg2 = Op2.getReg();
7446 unsigned Rt2 =
MRI->getEncodingValue(Reg2);
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");
7460 MCRegister NewReg =
MRI->getMatchingSuperReg(
7462 Operands[
Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7463 Op2.getEndLoc(), *
this);
7473 if (isThumbTwo() && Mnemonic ==
"sub" && CarrySetting &&
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(
"subs", 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)
7550 "SP may not be in the register list");
7551 if (ListContainsPC && ListContainsLR)
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)
7568 "SP and PC may not be in the register list");
7572 "SP may not be in the register list");
7576 "PC may not be in the register list");
7581 bool Load,
bool ARMMode,
bool Writeback,
7582 unsigned MnemonicOpsEndInd) {
7583 unsigned RtIndex =
Load || !Writeback ? 0 : 1;
7596 "Rt must be even-numbered");
7599 if (Rt2 != Rt + 1) {
7602 "destination operands must be sequential");
7605 "source operands must be sequential");
7612 if (!ARMMode &&
Load) {
7615 "destination operands can't be identical");
7621 if (Rn == Rt || Rn == Rt2) {
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();
7677 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isCondCode())
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) {
7724 if (
static_cast<ARMOperand &
>(*
Operands[
I]).isVPTPred())
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: {
7746 MnemonicOpsEndInd + 2) {
7747 ARMOperand &
Op =
static_cast<ARMOperand &
>(
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())
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))
7834 "operand must be a register in range [r0, r14]");
7836 case ARM::STR_PRE_IMM:
7837 case ARM::STR_PRE_REG:
7838 case ARM::t2STR_PRE:
7839 case ARM::STR_POST_IMM:
7840 case ARM::STR_POST_REG:
7841 case ARM::t2STR_POST:
7843 case ARM::t2STRH_PRE:
7844 case ARM::STRH_POST:
7845 case ARM::t2STRH_POST:
7846 case ARM::STRB_PRE_IMM:
7847 case ARM::STRB_PRE_REG:
7848 case ARM::t2STRB_PRE:
7849 case ARM::STRB_POST_IMM:
7850 case ARM::STRB_POST_REG:
7851 case ARM::t2STRB_POST: {
7857 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7858 "source register and base register can't be identical");
7861 case ARM::t2LDR_PRE_imm:
7862 case ARM::t2LDR_POST_imm:
7863 case ARM::t2STR_PRE_imm:
7864 case ARM::t2STR_POST_imm: {
7871 "destination register and base register can't be identical");
7872 if (Inst.
getOpcode() == ARM::t2LDR_POST_imm ||
7873 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7875 if (
Imm > 255 ||
Imm < -255)
7876 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7877 "operand must be in range [-255, 255]");
7879 if (Inst.
getOpcode() == ARM::t2STR_PRE_imm ||
7880 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7883 "operand must be a register in range [r0, r14]");
7889 case ARM::t2LDRB_OFFSET_imm:
7890 case ARM::t2LDRB_PRE_imm:
7891 case ARM::t2LDRB_POST_imm:
7892 case ARM::t2STRB_OFFSET_imm:
7893 case ARM::t2STRB_PRE_imm:
7894 case ARM::t2STRB_POST_imm: {
7895 if (Inst.
getOpcode() == ARM::t2LDRB_POST_imm ||
7896 Inst.
getOpcode() == ARM::t2STRB_POST_imm ||
7897 Inst.
getOpcode() == ARM::t2LDRB_PRE_imm ||
7898 Inst.
getOpcode() == ARM::t2STRB_PRE_imm) {
7900 if (
Imm > 255 ||
Imm < -255)
7901 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7902 "operand must be in range [-255, 255]");
7903 }
else if (Inst.
getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7904 Inst.
getOpcode() == ARM::t2STRB_OFFSET_imm) {
7906 if (
Imm > 0 ||
Imm < -255)
7907 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7908 "operand must be in range [0, 255] with a negative sign");
7912 "if operand is PC, should call the LDRB (literal)");
7917 case ARM::t2LDRH_OFFSET_imm:
7918 case ARM::t2LDRH_PRE_imm:
7919 case ARM::t2LDRH_POST_imm:
7920 case ARM::t2STRH_OFFSET_imm:
7921 case ARM::t2STRH_PRE_imm:
7922 case ARM::t2STRH_POST_imm: {
7923 if (Inst.
getOpcode() == ARM::t2LDRH_POST_imm ||
7924 Inst.
getOpcode() == ARM::t2STRH_POST_imm ||
7925 Inst.
getOpcode() == ARM::t2LDRH_PRE_imm ||
7926 Inst.
getOpcode() == ARM::t2STRH_PRE_imm) {
7928 if (
Imm > 255 ||
Imm < -255)
7929 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7930 "operand must be in range [-255, 255]");
7931 }
else if (Inst.
getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7932 Inst.
getOpcode() == ARM::t2STRH_OFFSET_imm) {
7934 if (
Imm > 0 ||
Imm < -255)
7935 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7936 "operand must be in range [0, 255] with a negative sign");
7940 "if operand is PC, should call the LDRH (literal)");
7945 case ARM::t2LDRSB_OFFSET_imm:
7946 case ARM::t2LDRSB_PRE_imm:
7947 case ARM::t2LDRSB_POST_imm: {
7948 if (Inst.
getOpcode() == ARM::t2LDRSB_POST_imm ||
7949 Inst.
getOpcode() == ARM::t2LDRSB_PRE_imm) {
7951 if (
Imm > 255 ||
Imm < -255)
7952 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7953 "operand must be in range [-255, 255]");
7954 }
else if (Inst.
getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7956 if (
Imm > 0 ||
Imm < -255)
7957 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7958 "operand must be in range [0, 255] with a negative sign");
7961 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7962 "if operand is PC, should call the LDRH (literal)");
7967 case ARM::t2LDRSH_OFFSET_imm:
7968 case ARM::t2LDRSH_PRE_imm:
7969 case ARM::t2LDRSH_POST_imm: {
7970 if (Inst.
getOpcode() == ARM::t2LDRSH_POST_imm ||
7971 Inst.
getOpcode() == ARM::t2LDRSH_PRE_imm) {
7973 if (
Imm > 255 ||
Imm < -255)
7974 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7975 "operand must be in range [-255, 255]");
7976 }
else if (Inst.
getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7978 if (
Imm > 0 ||
Imm < -255)
7979 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7980 "operand must be in range [0, 255] with a negative sign");
7984 "if operand is PC, should call the LDRH (literal)");
7989 case ARM::LDR_PRE_IMM:
7990 case ARM::LDR_PRE_REG:
7991 case ARM::t2LDR_PRE:
7992 case ARM::LDR_POST_IMM:
7993 case ARM::LDR_POST_REG:
7994 case ARM::t2LDR_POST:
7996 case ARM::t2LDRH_PRE:
7997 case ARM::LDRH_POST:
7998 case ARM::t2LDRH_POST:
7999 case ARM::LDRSH_PRE:
8000 case ARM::t2LDRSH_PRE:
8001 case ARM::LDRSH_POST:
8002 case ARM::t2LDRSH_POST:
8003 case ARM::LDRB_PRE_IMM:
8004 case ARM::LDRB_PRE_REG:
8005 case ARM::t2LDRB_PRE:
8006 case ARM::LDRB_POST_IMM:
8007 case ARM::LDRB_POST_REG:
8008 case ARM::t2LDRB_POST:
8009 case ARM::LDRSB_PRE:
8010 case ARM::t2LDRSB_PRE:
8011 case ARM::LDRSB_POST:
8012 case ARM::t2LDRSB_POST: {
8019 "destination register and base register can't be identical");
8023 case ARM::MVE_VLDRBU8_rq:
8024 case ARM::MVE_VLDRBU16_rq:
8025 case ARM::MVE_VLDRBS16_rq:
8026 case ARM::MVE_VLDRBU32_rq:
8027 case ARM::MVE_VLDRBS32_rq:
8028 case ARM::MVE_VLDRHU16_rq:
8029 case ARM::MVE_VLDRHU16_rq_u:
8030 case ARM::MVE_VLDRHU32_rq:
8031 case ARM::MVE_VLDRHU32_rq_u:
8032 case ARM::MVE_VLDRHS32_rq:
8033 case ARM::MVE_VLDRHS32_rq_u:
8034 case ARM::MVE_VLDRWU32_rq:
8035 case ARM::MVE_VLDRWU32_rq_u:
8036 case ARM::MVE_VLDRDU64_rq:
8037 case ARM::MVE_VLDRDU64_rq_u:
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRWU32_qi_pre:
8040 case ARM::MVE_VLDRDU64_qi:
8041 case ARM::MVE_VLDRDU64_qi_pre: {
8043 unsigned QdIdx = 0, QmIdx = 2;
8044 bool QmIsPointer =
false;
8046 case ARM::MVE_VLDRWU32_qi:
8047 case ARM::MVE_VLDRDU64_qi:
8051 case ARM::MVE_VLDRWU32_qi_pre:
8052 case ARM::MVE_VLDRDU64_qi_pre:
8063 Twine(
"destination vector register and vector ") +
8064 (QmIsPointer ?
"pointer" :
"offset") +
8065 " register can't be identical");
8077 if (Widthm1 >= 32 - LSB)
8078 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8079 "bitfield width must be in range [1,32-lsb]");
8091 bool HasWritebackToken =
8092 (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8094 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8097 bool ListContainsBase;
8102 "registers must be in range r0-r7");
8104 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8107 "writeback operator '!' expected");
8110 if (ListContainsBase && HasWritebackToken)
8111 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8112 "writeback operator '!' not allowed when base register "
8113 "in register list");
8115 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8119 case ARM::LDMIA_UPD:
8120 case ARM::LDMDB_UPD:
8121 case ARM::LDMIB_UPD:
8122 case ARM::LDMDA_UPD:
8129 "writeback register not allowed in register list");
8133 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8138 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8141 case ARM::t2LDMIA_UPD:
8142 case ARM::t2LDMDB_UPD:
8143 case ARM::t2STMIA_UPD:
8144 case ARM::t2STMDB_UPD:
8147 "writeback register not allowed in register list");
8149 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8150 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8153 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8158 case ARM::sysLDMIA_UPD:
8159 case ARM::sysLDMDA_UPD:
8160 case ARM::sysLDMDB_UPD:
8161 case ARM::sysLDMIB_UPD:
8163 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8164 "writeback register only allowed on system LDM "
8165 "if PC in register-list");
8167 case ARM::sysSTMIA_UPD:
8168 case ARM::sysSTMDA_UPD:
8169 case ARM::sysSTMDB_UPD:
8170 case ARM::sysSTMIB_UPD:
8172 "system STM cannot have writeback register");
8177 bool ListContainsBase;
8179 ListContainsBase) &&
8182 "registers must be in range r0-r7 or pc");
8183 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 2, !isMClass()))
8188 bool ListContainsBase;
8190 ListContainsBase) &&
8193 "registers must be in range r0-r7 or lr");
8194 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 2))
8198 case ARM::tSTMIA_UPD: {
8199 bool ListContainsBase, InvalidLowList;
8201 0, ListContainsBase);
8202 if (InvalidLowList && !isThumbTwo())
8203 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8204 "registers must be in range r0-r7");
8208 if (InvalidLowList && ListContainsBase)
8210 "writeback operator '!' not allowed when base register "
8211 "in register list");
8213 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 4))
8220 if (!isThumbTwo() &&
8222 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8223 "source register must be the same as destination");
8233 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8234 "source register must be sp if destination is sp");
8239 if (!(
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]))
8240 .isSignedOffset<11, 1>())
8242 "branch target out of range");
8245 int op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8246 : MnemonicOpsEndInd + 1;
8247 ARMOperand &Operand =
static_cast<ARMOperand &
>(*
Operands[
op]);
8250 !Operand.isSignedOffset<24, 1>())
8251 return Error(
Operands[
op]->getStartLoc(),
"branch target out of range");
8256 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8257 .isSignedOffset<8, 1>())
8259 "branch target out of range");
8262 int Op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8263 : MnemonicOpsEndInd + 1;
8264 if (!
static_cast<ARMOperand &
>(*
Operands[
Op]).isSignedOffset<20, 1>())
8265 return Error(
Operands[
Op]->getStartLoc(),
"branch target out of range");
8270 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8271 .isUnsignedOffset<6, 1>())
8272 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8273 "branch target out of range");
8279 case ARM::t2MOVTi16:
8287 int i = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8288 : MnemonicOpsEndInd + 1;
8289 ARMOperand &
Op =
static_cast<ARMOperand &
>(*
Operands[i]);
8290 const MCExpr *
E =
Op.getImm();
8294 if (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
8298 "immediate expression for mov requires :lower16: or :upper16");
8302 int i = (
Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8303 : MnemonicOpsEndInd + 2;
8306 return Error(
Op.getStartLoc(),
8307 "Immediate expression for Thumb adds requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8312 MCParsedAsmOperand &
Op = *
Operands[MnemonicOpsEndInd + 1];
8314 return Error(
Op.getStartLoc(),
8315 "Immediate expression for Thumb movs requires :lower0_7:,"
8316 " :lower8_15:, :upper0_7: or :upper8_15:");
8326 return Error(
Operands[1]->getStartLoc(),
"instruction 'esb' is not "
8327 "predicable, but condition "
8330 return Error(
Operands[1]->getStartLoc(),
"instruction 'csdb' is not "
8331 "predicable, but condition "
8339 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8340 .isUnsignedOffset<4, 1>() ||
8343 "branch location out of range or not a multiple of 2");
8346 if (Opcode == ARM::t2BFi) {
8347 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8348 .isSignedOffset<16, 1>())
8350 "branch target out of range or not a multiple of 2");
8351 }
else if (Opcode == ARM::t2BFLi) {
8352 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8353 .isSignedOffset<18, 1>())
8355 "branch target out of range or not a multiple of 2");
8360 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8361 .isUnsignedOffset<4, 1>() ||
8364 "branch location out of range or not a multiple of 2");
8366 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8367 .isSignedOffset<16, 1>())
8368 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8369 "branch target out of range or not a multiple of 2");
8372 "branch location and else branch target should either both be "
8373 "immediates or both labels");
8377 if (Diff != 4 && Diff != 2)
8380 "else branch target must be 2 or 4 greater than the branch location");
8387 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8390 "invalid register in register list. Valid registers are "
8391 "r0-r12, lr/r14 and APSR.");
8408 "instruction 'ssbb' is not predicable, but condition code "
8412 "instruction 'pssbb' is not predicable, but condition code "
8416 case ARM::VMOVRRS: {
8421 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8422 "source operands must be sequential");
8425 case ARM::VMOVSRR: {
8431 "destination operands must be sequential");
8435 case ARM::VSTMDIA: {
8437 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
8438 auto &RegList =
Op.getRegList();
8439 if (RegList.size() < 1 || RegList.size() > 16)
8440 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8441 "list of registers must be at least 1 and at most 16");
8444 case ARM::MVE_VQDMULLs32bh:
8445 case ARM::MVE_VQDMULLs32th:
8446 case ARM::MVE_VCMULf32:
8447 case ARM::MVE_VMULLBs32:
8448 case ARM::MVE_VMULLTs32:
8449 case ARM::MVE_VMULLBu32:
8450 case ARM::MVE_VMULLTu32: {
8454 "Qd register and Qn register can't be identical");
8459 "Qd register and Qm register can't be identical");
8463 case ARM::MVE_VREV64_8:
8464 case ARM::MVE_VREV64_16:
8465 case ARM::MVE_VREV64_32:
8466 case ARM::MVE_VQDMULL_qr_s32bh:
8467 case ARM::MVE_VQDMULL_qr_s32th: {
8471 "Qd register and Qn register can't be identical");
8475 case ARM::MVE_VCADDi32:
8476 case ARM::MVE_VCADDf32:
8477 case ARM::MVE_VHCADDs32: {
8481 "Qd register and Qm register can't be identical");
8485 case ARM::MVE_VMOV_rr_q: {
8488 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8489 "Q-registers must be the same");
8490 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8491 .getVectorIndex() !=
8492 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 5])
8495 return Error(
Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8496 "Q-register indexes must be 2 and 0 or 3 and 1");
8499 case ARM::MVE_VMOV_q_rr: {
8503 "Q-registers must be the same");
8504 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8505 .getVectorIndex() !=
8506 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8509 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8510 "Q-register indexes must be 2 and 0 or 3 and 1");
8513 case ARM::MVE_SQRSHR:
8514 case ARM::MVE_UQRSHL: {
8518 "Rda register and Rm register can't be identical");
8539 case ARM::t2SMLALBB:
8540 case ARM::t2SMLALBT:
8542 case ARM::t2SMLALDX:
8543 case ARM::t2SMLALTB:
8544 case ARM::t2SMLALTT:
8546 case ARM::t2SMLSLDX:
8547 case ARM::t2SMULL: {
8552 "unpredictable instruction, RdHi and RdLo must be different");
8560 case ARM::CDE_CX1DA:
8564 case ARM::CDE_CX2DA:
8568 case ARM::CDE_CX3DA:
8569 case ARM::CDE_VCX1_vec:
8570 case ARM::CDE_VCX1_fpsp:
8571 case ARM::CDE_VCX1_fpdp:
8572 case ARM::CDE_VCX1A_vec:
8573 case ARM::CDE_VCX1A_fpsp:
8574 case ARM::CDE_VCX1A_fpdp:
8575 case ARM::CDE_VCX2_vec:
8576 case ARM::CDE_VCX2_fpsp:
8577 case ARM::CDE_VCX2_fpdp:
8578 case ARM::CDE_VCX2A_vec:
8579 case ARM::CDE_VCX2A_fpsp:
8580 case ARM::CDE_VCX2A_fpdp:
8581 case ARM::CDE_VCX3_vec:
8582 case ARM::CDE_VCX3_fpsp:
8583 case ARM::CDE_VCX3_fpdp:
8584 case ARM::CDE_VCX3A_vec:
8585 case ARM::CDE_VCX3A_fpsp:
8586 case ARM::CDE_VCX3A_fpdp: {
8588 "CDE operand 1 must be a coprocessor ID");
8592 "coprocessor must be configured as CDE");
8593 else if (Coproc >= 8)
8595 "coprocessor must be in the range [p0, p7]");
8601 case ARM::t2LDC2L_OFFSET:
8602 case ARM::t2LDC2L_OPTION:
8603 case ARM::t2LDC2L_POST:
8604 case ARM::t2LDC2L_PRE:
8605 case ARM::t2LDC2_OFFSET:
8606 case ARM::t2LDC2_OPTION:
8607 case ARM::t2LDC2_POST:
8608 case ARM::t2LDC2_PRE:
8609 case ARM::t2LDCL_OFFSET:
8610 case ARM::t2LDCL_OPTION:
8611 case ARM::t2LDCL_POST:
8612 case ARM::t2LDCL_PRE:
8613 case ARM::t2LDC_OFFSET:
8614 case ARM::t2LDC_OPTION:
8615 case ARM::t2LDC_POST:
8616 case ARM::t2LDC_PRE:
8625 case ARM::t2STC2L_OFFSET:
8626 case ARM::t2STC2L_OPTION:
8627 case ARM::t2STC2L_POST:
8628 case ARM::t2STC2L_PRE:
8629 case ARM::t2STC2_OFFSET:
8630 case ARM::t2STC2_OPTION:
8631 case ARM::t2STC2_POST:
8632 case ARM::t2STC2_PRE:
8633 case ARM::t2STCL_OFFSET:
8634 case ARM::t2STCL_OPTION:
8635 case ARM::t2STCL_POST:
8636 case ARM::t2STCL_PRE:
8637 case ARM::t2STC_OFFSET:
8638 case ARM::t2STC_OPTION:
8639 case ARM::t2STC_POST:
8640 case ARM::t2STC_PRE: {
8645 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8647 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8650 "Operand must be a coprocessor ID");
8655 "coprocessor must be configured as GCP");
8686 "source and destination registers must be the same");
8698 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8699 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8700 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8701 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8702 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8703 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8704 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
8705 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
8706 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
8709 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8710 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8711 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8712 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8713 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8715 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8716 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8717 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8718 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8719 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8721 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
8722 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
8723 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
8724 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
8725 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
8728 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8729 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8730 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8731 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
8732 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8733 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8734 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8735 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8736 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
8737 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8738 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
8739 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
8740 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
8741 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
8742 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
8745 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8746 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8747 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8748 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8749 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8750 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8751 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8752 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8753 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8754 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8755 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8756 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8757 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
8758 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
8759 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
8760 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
8761 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
8762 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
8765 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8766 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8767 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8768 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
8769 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8770 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8771 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8772 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8773 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
8774 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8775 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
8776 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
8777 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
8778 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
8779 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
8782 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8783 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8784 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8785 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8786 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8787 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8788 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8789 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8790 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8791 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8792 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8793 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8794 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
8795 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
8796 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
8797 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
8798 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
8799 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
8807 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8808 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8809 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8810 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8811 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8812 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8813 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
8814 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
8815 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
8818 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8819 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8820 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8821 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
8822 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8823 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8824 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8825 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8826 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
8827 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8828 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
8829 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
8830 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
8831 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
8832 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
8835 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8836 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8837 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8838 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
8839 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8840 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8841 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8842 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8843 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8844 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
8845 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8846 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8847 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
8848 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
8849 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
8850 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
8851 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
8852 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
8855 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8856 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8857 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8858 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
8859 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8860 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8861 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8862 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8863 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
8864 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8865 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
8866 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
8867 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
8868 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
8869 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
8872 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8873 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8874 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8875 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8876 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8877 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8878 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8879 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8880 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8881 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8882 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8883 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8884 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
8885 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
8886 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
8887 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
8888 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
8889 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
8892 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8893 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8894 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8895 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8896 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8897 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8898 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8899 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8900 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8901 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8902 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
8903 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
8904 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
8905 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
8906 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
8909 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8910 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8911 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8912 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
8913 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
8914 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8915 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8916 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8917 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8918 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
8919 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
8920 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8921 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
8922 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
8923 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
8924 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
8925 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
8926 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
8929 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8930 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8931 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8932 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8933 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8934 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8935 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8936 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8937 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8938 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8939 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8940 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8941 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
8942 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
8943 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
8944 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
8945 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
8946 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
8950bool ARMAsmParser::processInstruction(MCInst &Inst,
8952 unsigned MnemonicOpsEndInd,
8956 bool HasWideQualifier =
false;
8958 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
8959 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
8960 HasWideQualifier =
true;
8971 MnemonicOpsEndInd + 2) {
8972 ARMOperand &
Op =
static_cast<ARMOperand &
>(
8975 auto &RegList =
Op.getRegList();
8978 if (RegList.size() == 32) {
8979 const unsigned Opcode =
8980 (Inst.
getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8994 case ARM::LDRT_POST:
8995 case ARM::LDRBT_POST: {
8996 const unsigned Opcode =
8997 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8998 : ARM::LDRBT_POST_IMM;
9014 case ARM::LDRSHTii: {
9019 else if (Inst.
getOpcode() == ARM::LDRHTii)
9021 else if (Inst.
getOpcode() == ARM::LDRSHTii)
9032 case ARM::STRT_POST:
9033 case ARM::STRBT_POST: {
9034 const unsigned Opcode =
9035 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9036 : ARM::STRBT_POST_IMM;
9085 case ARM::t2LDR_PRE_imm:
9086 case ARM::t2LDR_POST_imm: {
9100 case ARM::t2STR_PRE_imm:
9101 case ARM::t2STR_POST_imm: {
9115 case ARM::t2LDRB_OFFSET_imm: {
9125 case ARM::t2LDRB_PRE_imm:
9126 case ARM::t2LDRB_POST_imm: {
9130 : ARM::t2LDRB_POST);
9141 case ARM::t2STRB_OFFSET_imm: {
9151 case ARM::t2STRB_PRE_imm:
9152 case ARM::t2STRB_POST_imm: {
9156 : ARM::t2STRB_POST);
9167 case ARM::t2LDRH_OFFSET_imm: {
9177 case ARM::t2LDRH_PRE_imm:
9178 case ARM::t2LDRH_POST_imm: {
9182 : ARM::t2LDRH_POST);
9193 case ARM::t2STRH_OFFSET_imm: {
9203 case ARM::t2STRH_PRE_imm:
9204 case ARM::t2STRH_POST_imm: {
9208 : ARM::t2STRH_POST);
9219 case ARM::t2LDRSB_OFFSET_imm: {
9229 case ARM::t2LDRSB_PRE_imm:
9230 case ARM::t2LDRSB_POST_imm: {
9234 : ARM::t2LDRSB_POST);
9245 case ARM::t2LDRSH_OFFSET_imm: {
9255 case ARM::t2LDRSH_PRE_imm:
9256 case ARM::t2LDRSH_POST_imm: {
9260 : ARM::t2LDRSH_POST);
9271 case ARM::t2LDRpcrel:
9280 case ARM::t2LDRBpcrel:
9283 case ARM::t2LDRHpcrel:
9286 case ARM::t2LDRSBpcrel:
9289 case ARM::t2LDRSHpcrel:
9292 case ARM::LDRConstPool:
9293 case ARM::tLDRConstPool:
9294 case ARM::t2LDRConstPool: {
9299 if (Inst.
getOpcode() == ARM::LDRConstPool)
9301 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
9303 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
9305 const ARMOperand &PoolOperand =
9306 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
9307 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9314 bool MovHasS =
true;
9315 if (Inst.
getOpcode() == ARM::LDRConstPool) {
9325 else if (hasV6T2Ops() &&
9338 else if (hasThumb2() &&
9343 else if (hasV8MBaseline() &&
9363 const MCExpr *CPLoc =
9364 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9365 PoolOperand.getStartLoc());
9376 case ARM::VST1LNdWB_register_Asm_8:
9377 case ARM::VST1LNdWB_register_Asm_16:
9378 case ARM::VST1LNdWB_register_Asm_32: {
9396 case ARM::VST2LNdWB_register_Asm_8:
9397 case ARM::VST2LNdWB_register_Asm_16:
9398 case ARM::VST2LNdWB_register_Asm_32:
9399 case ARM::VST2LNqWB_register_Asm_16:
9400 case ARM::VST2LNqWB_register_Asm_32: {
9420 case ARM::VST3LNdWB_register_Asm_8:
9421 case ARM::VST3LNdWB_register_Asm_16:
9422 case ARM::VST3LNdWB_register_Asm_32:
9423 case ARM::VST3LNqWB_register_Asm_16:
9424 case ARM::VST3LNqWB_register_Asm_32: {
9446 case ARM::VST4LNdWB_register_Asm_8:
9447 case ARM::VST4LNdWB_register_Asm_16:
9448 case ARM::VST4LNdWB_register_Asm_32:
9449 case ARM::VST4LNqWB_register_Asm_16:
9450 case ARM::VST4LNqWB_register_Asm_32: {
9474 case ARM::VST1LNdWB_fixed_Asm_8:
9475 case ARM::VST1LNdWB_fixed_Asm_16:
9476 case ARM::VST1LNdWB_fixed_Asm_32: {
9494 case ARM::VST2LNdWB_fixed_Asm_8:
9495 case ARM::VST2LNdWB_fixed_Asm_16:
9496 case ARM::VST2LNdWB_fixed_Asm_32:
9497 case ARM::VST2LNqWB_fixed_Asm_16:
9498 case ARM::VST2LNqWB_fixed_Asm_32: {
9518 case ARM::VST3LNdWB_fixed_Asm_8:
9519 case ARM::VST3LNdWB_fixed_Asm_16:
9520 case ARM::VST3LNdWB_fixed_Asm_32:
9521 case ARM::VST3LNqWB_fixed_Asm_16:
9522 case ARM::VST3LNqWB_fixed_Asm_32: {
9544 case ARM::VST4LNdWB_fixed_Asm_8:
9545 case ARM::VST4LNdWB_fixed_Asm_16:
9546 case ARM::VST4LNdWB_fixed_Asm_32:
9547 case ARM::VST4LNqWB_fixed_Asm_16:
9548 case ARM::VST4LNqWB_fixed_Asm_32: {
9572 case ARM::VST1LNdAsm_8:
9573 case ARM::VST1LNdAsm_16:
9574 case ARM::VST1LNdAsm_32: {
9590 case ARM::VST2LNdAsm_8:
9591 case ARM::VST2LNdAsm_16:
9592 case ARM::VST2LNdAsm_32:
9593 case ARM::VST2LNqAsm_16:
9594 case ARM::VST2LNqAsm_32: {
9612 case ARM::VST3LNdAsm_8:
9613 case ARM::VST3LNdAsm_16:
9614 case ARM::VST3LNdAsm_32:
9615 case ARM::VST3LNqAsm_16:
9616 case ARM::VST3LNqAsm_32: {
9636 case ARM::VST4LNdAsm_8:
9637 case ARM::VST4LNdAsm_16:
9638 case ARM::VST4LNdAsm_32:
9639 case ARM::VST4LNqAsm_16:
9640 case ARM::VST4LNqAsm_32: {
9663 case ARM::VLD1LNdWB_register_Asm_8:
9664 case ARM::VLD1LNdWB_register_Asm_16:
9665 case ARM::VLD1LNdWB_register_Asm_32: {
9684 case ARM::VLD2LNdWB_register_Asm_8:
9685 case ARM::VLD2LNdWB_register_Asm_16:
9686 case ARM::VLD2LNdWB_register_Asm_32:
9687 case ARM::VLD2LNqWB_register_Asm_16:
9688 case ARM::VLD2LNqWB_register_Asm_32: {
9711 case ARM::VLD3LNdWB_register_Asm_8:
9712 case ARM::VLD3LNdWB_register_Asm_16:
9713 case ARM::VLD3LNdWB_register_Asm_32:
9714 case ARM::VLD3LNqWB_register_Asm_16:
9715 case ARM::VLD3LNqWB_register_Asm_32: {
9742 case ARM::VLD4LNdWB_register_Asm_8:
9743 case ARM::VLD4LNdWB_register_Asm_16:
9744 case ARM::VLD4LNdWB_register_Asm_32:
9745 case ARM::VLD4LNqWB_register_Asm_16:
9746 case ARM::VLD4LNqWB_register_Asm_32: {
9777 case ARM::VLD1LNdWB_fixed_Asm_8:
9778 case ARM::VLD1LNdWB_fixed_Asm_16:
9779 case ARM::VLD1LNdWB_fixed_Asm_32: {
9798 case ARM::VLD2LNdWB_fixed_Asm_8:
9799 case ARM::VLD2LNdWB_fixed_Asm_16:
9800 case ARM::VLD2LNdWB_fixed_Asm_32:
9801 case ARM::VLD2LNqWB_fixed_Asm_16:
9802 case ARM::VLD2LNqWB_fixed_Asm_32: {
9825 case ARM::VLD3LNdWB_fixed_Asm_8:
9826 case ARM::VLD3LNdWB_fixed_Asm_16:
9827 case ARM::VLD3LNdWB_fixed_Asm_32:
9828 case ARM::VLD3LNqWB_fixed_Asm_16:
9829 case ARM::VLD3LNqWB_fixed_Asm_32: {
9856 case ARM::VLD4LNdWB_fixed_Asm_8:
9857 case ARM::VLD4LNdWB_fixed_Asm_16:
9858 case ARM::VLD4LNdWB_fixed_Asm_32:
9859 case ARM::VLD4LNqWB_fixed_Asm_16:
9860 case ARM::VLD4LNqWB_fixed_Asm_32: {
9891 case ARM::VLD1LNdAsm_8:
9892 case ARM::VLD1LNdAsm_16:
9893 case ARM::VLD1LNdAsm_32: {
9910 case ARM::VLD2LNdAsm_8:
9911 case ARM::VLD2LNdAsm_16:
9912 case ARM::VLD2LNdAsm_32:
9913 case ARM::VLD2LNqAsm_16:
9914 case ARM::VLD2LNqAsm_32: {
9935 case ARM::VLD3LNdAsm_8:
9936 case ARM::VLD3LNdAsm_16:
9937 case ARM::VLD3LNdAsm_32:
9938 case ARM::VLD3LNqAsm_16:
9939 case ARM::VLD3LNqAsm_32: {
9964 case ARM::VLD4LNdAsm_8:
9965 case ARM::VLD4LNdAsm_16:
9966 case ARM::VLD4LNdAsm_32:
9967 case ARM::VLD4LNqAsm_16:
9968 case ARM::VLD4LNqAsm_32: {
9998 case ARM::VLD3DUPdAsm_8:
9999 case ARM::VLD3DUPdAsm_16:
10000 case ARM::VLD3DUPdAsm_32:
10001 case ARM::VLD3DUPqAsm_8:
10002 case ARM::VLD3DUPqAsm_16:
10003 case ARM::VLD3DUPqAsm_32: {
10020 case ARM::VLD3DUPdWB_fixed_Asm_8:
10021 case ARM::VLD3DUPdWB_fixed_Asm_16:
10022 case ARM::VLD3DUPdWB_fixed_Asm_32:
10023 case ARM::VLD3DUPqWB_fixed_Asm_8:
10024 case ARM::VLD3DUPqWB_fixed_Asm_16:
10025 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10044 case ARM::VLD3DUPdWB_register_Asm_8:
10045 case ARM::VLD3DUPdWB_register_Asm_16:
10046 case ARM::VLD3DUPdWB_register_Asm_32:
10047 case ARM::VLD3DUPqWB_register_Asm_8:
10048 case ARM::VLD3DUPqWB_register_Asm_16:
10049 case ARM::VLD3DUPqWB_register_Asm_32: {
10069 case ARM::VLD3dAsm_8:
10070 case ARM::VLD3dAsm_16:
10071 case ARM::VLD3dAsm_32:
10072 case ARM::VLD3qAsm_8:
10073 case ARM::VLD3qAsm_16:
10074 case ARM::VLD3qAsm_32: {
10091 case ARM::VLD3dWB_fixed_Asm_8:
10092 case ARM::VLD3dWB_fixed_Asm_16:
10093 case ARM::VLD3dWB_fixed_Asm_32:
10094 case ARM::VLD3qWB_fixed_Asm_8:
10095 case ARM::VLD3qWB_fixed_Asm_16:
10096 case ARM::VLD3qWB_fixed_Asm_32: {
10115 case ARM::VLD3dWB_register_Asm_8:
10116 case ARM::VLD3dWB_register_Asm_16:
10117 case ARM::VLD3dWB_register_Asm_32:
10118 case ARM::VLD3qWB_register_Asm_8:
10119 case ARM::VLD3qWB_register_Asm_16:
10120 case ARM::VLD3qWB_register_Asm_32: {
10140 case ARM::VLD4DUPdAsm_8:
10141 case ARM::VLD4DUPdAsm_16:
10142 case ARM::VLD4DUPdAsm_32:
10143 case ARM::VLD4DUPqAsm_8:
10144 case ARM::VLD4DUPqAsm_16:
10145 case ARM::VLD4DUPqAsm_32: {
10164 case ARM::VLD4DUPdWB_fixed_Asm_8:
10165 case ARM::VLD4DUPdWB_fixed_Asm_16:
10166 case ARM::VLD4DUPdWB_fixed_Asm_32:
10167 case ARM::VLD4DUPqWB_fixed_Asm_8:
10168 case ARM::VLD4DUPqWB_fixed_Asm_16:
10169 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10190 case ARM::VLD4DUPdWB_register_Asm_8:
10191 case ARM::VLD4DUPdWB_register_Asm_16:
10192 case ARM::VLD4DUPdWB_register_Asm_32:
10193 case ARM::VLD4DUPqWB_register_Asm_8:
10194 case ARM::VLD4DUPqWB_register_Asm_16:
10195 case ARM::VLD4DUPqWB_register_Asm_32: {
10217 case ARM::VLD4dAsm_8:
10218 case ARM::VLD4dAsm_16:
10219 case ARM::VLD4dAsm_32:
10220 case ARM::VLD4qAsm_8:
10221 case ARM::VLD4qAsm_16:
10222 case ARM::VLD4qAsm_32: {
10241 case ARM::VLD4dWB_fixed_Asm_8:
10242 case ARM::VLD4dWB_fixed_Asm_16:
10243 case ARM::VLD4dWB_fixed_Asm_32:
10244 case ARM::VLD4qWB_fixed_Asm_8:
10245 case ARM::VLD4qWB_fixed_Asm_16:
10246 case ARM::VLD4qWB_fixed_Asm_32: {
10267 case ARM::VLD4dWB_register_Asm_8:
10268 case ARM::VLD4dWB_register_Asm_16:
10269 case ARM::VLD4dWB_register_Asm_32:
10270 case ARM::VLD4qWB_register_Asm_8:
10271 case ARM::VLD4qWB_register_Asm_16:
10272 case ARM::VLD4qWB_register_Asm_32: {
10294 case ARM::VST3dAsm_8:
10295 case ARM::VST3dAsm_16:
10296 case ARM::VST3dAsm_32:
10297 case ARM::VST3qAsm_8:
10298 case ARM::VST3qAsm_16:
10299 case ARM::VST3qAsm_32: {
10316 case ARM::VST3dWB_fixed_Asm_8:
10317 case ARM::VST3dWB_fixed_Asm_16:
10318 case ARM::VST3dWB_fixed_Asm_32:
10319 case ARM::VST3qWB_fixed_Asm_8:
10320 case ARM::VST3qWB_fixed_Asm_16:
10321 case ARM::VST3qWB_fixed_Asm_32: {
10340 case ARM::VST3dWB_register_Asm_8:
10341 case ARM::VST3dWB_register_Asm_16:
10342 case ARM::VST3dWB_register_Asm_32:
10343 case ARM::VST3qWB_register_Asm_8:
10344 case ARM::VST3qWB_register_Asm_16:
10345 case ARM::VST3qWB_register_Asm_32: {
10365 case ARM::VST4dAsm_8:
10366 case ARM::VST4dAsm_16:
10367 case ARM::VST4dAsm_32:
10368 case ARM::VST4qAsm_8:
10369 case ARM::VST4qAsm_16:
10370 case ARM::VST4qAsm_32: {
10389 case ARM::VST4dWB_fixed_Asm_8:
10390 case ARM::VST4dWB_fixed_Asm_16:
10391 case ARM::VST4dWB_fixed_Asm_32:
10392 case ARM::VST4qWB_fixed_Asm_8:
10393 case ARM::VST4qWB_fixed_Asm_16:
10394 case ARM::VST4qWB_fixed_Asm_32: {
10415 case ARM::VST4dWB_register_Asm_8:
10416 case ARM::VST4dWB_register_Asm_16:
10417 case ARM::VST4dWB_register_Asm_32:
10418 case ARM::VST4qWB_register_Asm_8:
10419 case ARM::VST4qWB_register_Asm_16:
10420 case ARM::VST4qWB_register_Asm_32: {
10448 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10449 !HasWideQualifier) {
10453 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
10454 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
10455 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
10473 case ARM::t2MOVSsr: {
10477 bool isNarrow =
false;
10482 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr) &&
10489 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
10490 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
10491 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
10492 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
10498 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10505 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10510 case ARM::t2MOVSsi: {
10514 bool isNarrow =
false;
10517 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi) &&
10524 bool isMov =
false;
10535 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10539 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
10540 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
10541 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
10542 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
10543 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
10546 if (Amount == 32) Amount = 0;
10549 if (isNarrow && !isMov)
10551 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10553 if (newOpc != ARM::t2RRX && !isMov)
10559 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10603 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10612 if (
Opc == ARM::MOVsi)
10633 case ARM::t2LDMIA_UPD: {
10649 case ARM::t2STMDB_UPD: {
10665 case ARM::LDMIA_UPD:
10683 case ARM::STMDB_UPD:
10699 case ARM::t2ADDri12:
10700 case ARM::t2SUBri12:
10701 case ARM::t2ADDspImm12:
10702 case ARM::t2SUBspImm12: {
10705 const StringRef Token =
static_cast<ARMOperand &
>(*
Operands[0]).
getToken();
10706 if ((Token !=
"add" && Token !=
"sub") ||
10710 case ARM::t2ADDri12:
10713 case ARM::t2SUBri12:
10716 case ARM::t2ADDspImm12:
10719 case ARM::t2SUBspImm12:
10734 Operands.size() == MnemonicOpsEndInd + 3) {
10745 Operands.size() == MnemonicOpsEndInd + 3) {
10751 case ARM::t2SUBri: {
10756 if (HasWideQualifier)
10763 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10769 int i = (
Operands[MnemonicOpsEndInd + 1]->isImm())
10770 ? MnemonicOpsEndInd + 1
10771 : MnemonicOpsEndInd + 2;
10778 ARM::tADDi8 : ARM::tSUBi8);
10788 case ARM::t2ADDspImm:
10789 case ARM::t2SUBspImm: {
10794 if (
V & 3 ||
V > ((1 << 7) - 1) << 2)
10807 case ARM::t2ADDrr: {
10869 case ARM::tLDMIA: {
10875 bool hasWritebackToken =
10876 (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
10878 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
10880 bool listContainsBase;
10882 (!listContainsBase && !hasWritebackToken) ||
10883 (listContainsBase && hasWritebackToken)) {
10886 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10889 if (hasWritebackToken)
10896 case ARM::tSTMIA_UPD: {
10901 bool listContainsBase;
10911 bool listContainsBase;
10925 bool listContainsBase;
10942 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10943 !HasWideQualifier) {
10964 !HasWideQualifier) {
10971 if (
Op == ARM::tMOVr) {
10989 !HasWideQualifier) {
10993 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
10994 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
10995 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
10996 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
11034 case ARM::ADDrsi: {
11040 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
11041 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
11042 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
11043 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
11044 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
11045 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
11068 assert(!inITBlock() &&
"nested IT blocks?!");
11084 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11085 !HasWideQualifier) {
11089 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
11090 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
11091 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
11092 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
11093 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
11094 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
11121 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11122 !HasWideQualifier) {
11126 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
11127 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
11128 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
11129 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
11148 case ARM::MVE_VPST:
11149 case ARM::MVE_VPTv16i8:
11150 case ARM::MVE_VPTv8i16:
11151 case ARM::MVE_VPTv4i32:
11152 case ARM::MVE_VPTv16u8:
11153 case ARM::MVE_VPTv8u16:
11154 case ARM::MVE_VPTv4u32:
11155 case ARM::MVE_VPTv16s8:
11156 case ARM::MVE_VPTv8s16:
11157 case ARM::MVE_VPTv4s32:
11158 case ARM::MVE_VPTv4f32:
11159 case ARM::MVE_VPTv8f16:
11160 case ARM::MVE_VPTv16i8r:
11161 case ARM::MVE_VPTv8i16r:
11162 case ARM::MVE_VPTv4i32r:
11163 case ARM::MVE_VPTv16u8r:
11164 case ARM::MVE_VPTv8u16r:
11165 case ARM::MVE_VPTv4u32r:
11166 case ARM::MVE_VPTv16s8r:
11167 case ARM::MVE_VPTv8s16r:
11168 case ARM::MVE_VPTv4s32r:
11169 case ARM::MVE_VPTv4f32r:
11170 case ARM::MVE_VPTv8f16r: {
11171 assert(!inVPTBlock() &&
"Nested VPT blocks are not allowed");
11173 VPTState.Mask = MO.
getImm();
11174 VPTState.CurPosition = 0;
11182ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11191 ((
isThumb() && !isThumbOne()) || hasV6MOps())) {
11192 return Match_MnemonicFail;
11197 return Match_Success;
11201unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11205 const MCInstrDesc &MCID = MII.get(
Opc);
11208 "optionally flag setting instruction missing optional def operand");
11210 "operand count mismatch!");
11211 bool IsCPSR =
false;
11213 for (
unsigned OpNo = 0; OpNo < MCID.
NumOperands; ++OpNo) {
11214 if (MCID.
operands()[OpNo].isOptionalDef() &&
11221 if (isThumbOne() && !IsCPSR)
11222 return Match_RequiresFlagSetting;
11225 if (isThumbTwo() && !IsCPSR && !inITBlock())
11226 return Match_RequiresITBlock;
11227 if (isThumbTwo() && IsCPSR && inITBlock())
11228 return Match_RequiresNotITBlock;
11231 return Match_RequiresNotITBlock;
11232 }
else if (isThumbOne()) {
11235 if (
Opc == ARM::tADDhirr && !hasV6MOps() &&
11238 return Match_RequiresThumb2;
11240 else if (
Opc == ARM::tMOVr && !hasV6Ops() &&
11243 return Match_RequiresV6;
11249 if (
Opc == ARM::t2MOVr && !hasV8Ops())
11254 return Match_RequiresV8;
11259 return Match_RequiresV8;
11265 case ARM::VMRS_FPCXTS:
11266 case ARM::VMRS_FPCXTNS:
11267 case ARM::VMSR_FPCXTS:
11268 case ARM::VMSR_FPCXTNS:
11269 case ARM::VMRS_FPSCR_NZCVQC:
11270 case ARM::VMSR_FPSCR_NZCVQC:
11272 case ARM::VMRS_VPR:
11274 case ARM::VMSR_VPR:
11280 return Match_InvalidOperand;
11286 return Match_RequiresV8;
11294 return Match_InvalidTiedOperand;
11301 if (MCID.
operands()[
I].RegClass == ARM::rGPRRegClassID) {
11316 MCRegister
Reg =
Op.getReg();
11317 if ((
Reg == ARM::SP) && !hasV8Ops())
11318 return Match_RequiresV8;
11319 else if (
Reg == ARM::PC)
11320 return Match_InvalidOperand;
11323 return Match_Success;
11336bool ARMAsmParser::isITBlockTerminator(MCInst &Inst)
const {
11337 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11354 SmallVectorImpl<NearMissInfo> &NearMisses,
11355 bool MatchingInlineAsm,
11356 bool &EmitInITBlock,
11359 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11360 return MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
11364 if (inImplicitITBlock()) {
11365 extendImplicitITBlock(ITState.Cond);
11366 if (MatchInstructionImpl(
Operands, Inst,
nullptr, MatchingInlineAsm) ==
11370 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11376 if (InstCond == ITCond) {
11377 EmitInITBlock =
true;
11378 return Match_Success;
11380 invertCurrentITCondition();
11381 EmitInITBlock =
true;
11382 return Match_Success;
11386 rewindImplicitITPosition();
11390 flushPendingInstructions(Out);
11391 unsigned PlainMatchResult =
11392 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
11393 if (PlainMatchResult == Match_Success) {
11394 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11402 EmitInITBlock =
false;
11403 return Match_Success;
11406 EmitInITBlock =
false;
11407 return Match_Success;
11410 EmitInITBlock =
false;
11411 return Match_Success;
11418 startImplicitITBlock();
11419 if (MatchInstructionImpl(
Operands, Inst,
nullptr, MatchingInlineAsm) ==
11421 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11426 EmitInITBlock =
true;
11427 return Match_Success;
11430 discardImplicitITBlock();
11434 EmitInITBlock =
false;
11435 return PlainMatchResult;
11439 unsigned VariantID = 0);
11442bool ARMAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
11445 bool MatchingInlineAsm) {
11447 unsigned MatchResult;
11448 bool PendConditionalInstruction =
false;
11451 MatchResult = MatchInstruction(
Operands, Inst, NearMisses, MatchingInlineAsm,
11452 PendConditionalInstruction, Out);
11457 switch (MatchResult) {
11458 case Match_Success:
11465 if (validateInstruction(Inst,
Operands, MnemonicOpsEndInd)) {
11468 forwardITPosition();
11469 forwardVPTPosition();
11478 while (processInstruction(Inst,
Operands, MnemonicOpsEndInd, Out))
11487 forwardITPosition();
11488 forwardVPTPosition();
11496 if (PendConditionalInstruction) {
11497 PendingConditionalInsts.
push_back(Inst);
11498 if (isITBlockFull() || isITBlockTerminator(Inst))
11499 flushPendingInstructions(Out);
11501 Out.emitInstruction(Inst, getSTI());
11504 case Match_NearMisses:
11505 ReportNearMisses(NearMisses, IDLoc,
Operands);
11507 case Match_MnemonicFail: {
11508 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11511 return Error(IDLoc,
"invalid instruction" + Suggestion,
11512 ((ARMOperand &)*
Operands[0]).getLocRange());
11520bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11526 if (IDVal ==
".word")
11527 parseLiteralValues(4, DirectiveID.
getLoc());
11528 else if (IDVal ==
".short" || IDVal ==
".hword")
11529 parseLiteralValues(2, DirectiveID.
getLoc());
11530 else if (IDVal ==
".thumb")
11531 parseDirectiveThumb(DirectiveID.
getLoc());
11532 else if (IDVal ==
".arm")
11533 parseDirectiveARM(DirectiveID.
getLoc());
11534 else if (IDVal ==
".thumb_func")
11535 parseDirectiveThumbFunc(DirectiveID.
getLoc());
11536 else if (IDVal ==
".code")
11537 parseDirectiveCode(DirectiveID.
getLoc());
11538 else if (IDVal ==
".syntax")
11539 parseDirectiveSyntax(DirectiveID.
getLoc());
11540 else if (IDVal ==
".unreq")
11541 parseDirectiveUnreq(DirectiveID.
getLoc());
11542 else if (IDVal ==
".fnend")
11543 parseDirectiveFnEnd(DirectiveID.
getLoc());
11544 else if (IDVal ==
".cantunwind")
11545 parseDirectiveCantUnwind(DirectiveID.
getLoc());
11546 else if (IDVal ==
".personality")
11547 parseDirectivePersonality(DirectiveID.
getLoc());
11548 else if (IDVal ==
".handlerdata")
11549 parseDirectiveHandlerData(DirectiveID.
getLoc());
11550 else if (IDVal ==
".setfp")
11551 parseDirectiveSetFP(DirectiveID.
getLoc());
11552 else if (IDVal ==
".pad")
11553 parseDirectivePad(DirectiveID.
getLoc());
11554 else if (IDVal ==
".save")
11555 parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
11556 else if (IDVal ==
".vsave")
11557 parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
11558 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
11559 parseDirectiveLtorg(DirectiveID.
getLoc());
11560 else if (IDVal ==
".even")
11561 parseDirectiveEven(DirectiveID.
getLoc());
11562 else if (IDVal ==
".personalityindex")
11563 parseDirectivePersonalityIndex(DirectiveID.
getLoc());
11564 else if (IDVal ==
".unwind_raw")
11565 parseDirectiveUnwindRaw(DirectiveID.
getLoc());
11566 else if (IDVal ==
".movsp")
11567 parseDirectiveMovSP(DirectiveID.
getLoc());
11568 else if (IDVal ==
".arch_extension")
11569 parseDirectiveArchExtension(DirectiveID.
getLoc());
11570 else if (IDVal ==
".align")
11571 return parseDirectiveAlign(DirectiveID.
getLoc());
11572 else if (IDVal ==
".thumb_set")
11573 parseDirectiveThumbSet(DirectiveID.
getLoc());
11574 else if (IDVal ==
".inst")
11575 parseDirectiveInst(DirectiveID.
getLoc());
11576 else if (IDVal ==
".inst.n")
11577 parseDirectiveInst(DirectiveID.
getLoc(),
'n');
11578 else if (IDVal ==
".inst.w")
11579 parseDirectiveInst(DirectiveID.
getLoc(),
'w');
11580 else if (!IsMachO && !IsCOFF) {
11581 if (IDVal ==
".arch")
11582 parseDirectiveArch(DirectiveID.
getLoc());
11583 else if (IDVal ==
".cpu")
11584 parseDirectiveCPU(DirectiveID.
getLoc());
11585 else if (IDVal ==
".eabi_attribute")
11586 parseDirectiveEabiAttr(DirectiveID.
getLoc());
11587 else if (IDVal ==
".fpu")
11588 parseDirectiveFPU(DirectiveID.
getLoc());
11589 else if (IDVal ==
".fnstart")
11590 parseDirectiveFnStart(DirectiveID.
getLoc());
11591 else if (IDVal ==
".object_arch")
11592 parseDirectiveObjectArch(DirectiveID.
getLoc());
11593 else if (IDVal ==
".tlsdescseq")
11594 parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
11597 }
else if (IsCOFF) {
11598 if (IDVal ==
".seh_stackalloc")
11599 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
false);
11600 else if (IDVal ==
".seh_stackalloc_w")
11601 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
true);
11602 else if (IDVal ==
".seh_save_regs")
11603 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
false);
11604 else if (IDVal ==
".seh_save_regs_w")
11605 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
true);
11606 else if (IDVal ==
".seh_save_sp")
11607 parseDirectiveSEHSaveSP(DirectiveID.
getLoc());
11608 else if (IDVal ==
".seh_save_fregs")
11609 parseDirectiveSEHSaveFRegs(DirectiveID.
getLoc());
11610 else if (IDVal ==
".seh_save_lr")
11611 parseDirectiveSEHSaveLR(DirectiveID.
getLoc());
11612 else if (IDVal ==
".seh_endprologue")
11613 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
false);
11614 else if (IDVal ==
".seh_endprologue_fragment")
11615 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
true);
11616 else if (IDVal ==
".seh_nop")
11617 parseDirectiveSEHNop(DirectiveID.
getLoc(),
false);
11618 else if (IDVal ==
".seh_nop_w")
11619 parseDirectiveSEHNop(DirectiveID.
getLoc(),
true);
11620 else if (IDVal ==
".seh_startepilogue")
11621 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
false);
11622 else if (IDVal ==
".seh_startepilogue_cond")
11623 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
true);
11624 else if (IDVal ==
".seh_endepilogue")
11625 parseDirectiveSEHEpilogEnd(DirectiveID.
getLoc());
11626 else if (IDVal ==
".seh_custom")
11627 parseDirectiveSEHCustom(DirectiveID.
getLoc());
11639bool ARMAsmParser::parseLiteralValues(
unsigned Size, SMLoc L) {
11640 auto parseOne = [&]() ->
bool {
11641 const MCExpr *
Value;
11642 if (getParser().parseExpression(
Value))
11644 getParser().getStreamer().emitValue(
Value,
Size, L);
11647 return (parseMany(parseOne));
11652bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11653 if (parseEOL() || check(!hasThumb(), L,
"target does not support Thumb mode"))
11659 getTargetStreamer().emitCode16();
11660 getParser().getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
11666bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11667 if (parseEOL() || check(!hasARM(), L,
"target does not support ARM mode"))
11672 getTargetStreamer().emitCode32();
11673 getParser().getStreamer().emitCodeAlignment(
Align(4), getSTI(), 0);
11677void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11680 flushPendingInstructions(getStreamer());
11683void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11684 if (NextSymbolIsThumb) {
11685 getTargetStreamer().emitThumbFunc(Symbol);
11686 NextSymbolIsThumb =
false;
11692bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11693 MCAsmParser &Parser = getParser();
11703 MCSymbol *
Func = getParser().getContext().getOrCreateSymbol(
11705 getTargetStreamer().emitThumbFunc(Func);
11720 getTargetStreamer().emitCode16();
11722 NextSymbolIsThumb =
true;
11728bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11729 MCAsmParser &Parser = getParser();
11730 const AsmToken &Tok = Parser.
getTok();
11732 Error(L,
"unexpected token in .syntax directive");
11738 if (check(
Mode ==
"divided" ||
Mode ==
"DIVIDED", L,
11739 "'.syntax divided' arm assembly not supported") ||
11740 check(
Mode !=
"unified" &&
Mode !=
"UNIFIED", L,
11741 "unrecognized syntax mode in .syntax directive") ||
11752bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11753 MCAsmParser &Parser = getParser();
11754 const AsmToken &Tok = Parser.
getTok();
11756 return Error(L,
"unexpected token in .code directive");
11758 if (Val != 16 && Val != 32) {
11759 Error(L,
"invalid operand to .code directive");
11769 return Error(L,
"target does not support Thumb mode");
11773 getTargetStreamer().emitCode16();
11776 return Error(L,
"target does not support ARM mode");
11780 getTargetStreamer().emitCode32();
11788bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11789 MCAsmParser &Parser = getParser();
11792 SMLoc SRegLoc, ERegLoc;
11793 const bool parseResult = parseRegister(
Reg, SRegLoc, ERegLoc);
11794 if (check(parseResult, SRegLoc,
"register name expected") || parseEOL())
11797 if (RegisterReqs.
insert(std::make_pair(Name,
Reg)).first->second !=
Reg)
11798 return Error(SRegLoc,
11799 "redefinition of '" + Name +
"' does not match original.");
11806bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11807 MCAsmParser &Parser = getParser();
11809 return Error(L,
"unexpected input in .unreq directive.");
11818void ARMAsmParser::FixModeAfterArchChange(
bool WasThumb, SMLoc Loc) {
11820 if (WasThumb && hasThumb()) {
11823 }
else if (!WasThumb && hasARM()) {
11829 getTargetStreamer().emitCode16();
11831 getTargetStreamer().emitCode32();
11835 Warning(Loc, Twine(
"new target does not support ") +
11836 (WasThumb ?
"thumb" :
"arm") +
" mode, switching to " +
11837 (!WasThumb ?
"thumb" :
"arm") +
" mode");
11844bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11845 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11848 if (ID == ARM::ArchKind::INVALID)
11849 return Error(L,
"Unknown arch name");
11852 MCSubtargetInfo &STI = copySTI();
11855 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11856 FixModeAfterArchChange(WasThumb, L);
11858 getTargetStreamer().emitArch(ID);
11865bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11866 MCAsmParser &Parser = getParser();
11875 Error(TagLoc,
"attribute name not recognised: " + Name);
11881 const MCExpr *AttrExpr;
11888 if (check(!CE, TagLoc,
"expected numeric constant"))
11891 Tag =
CE->getValue();
11897 StringRef StringValue =
"";
11898 bool IsStringValue =
false;
11900 int64_t IntegerValue = 0;
11901 bool IsIntegerValue =
false;
11904 IsStringValue =
true;
11906 IsStringValue =
true;
11907 IsIntegerValue =
true;
11908 }
else if (
Tag < 32 ||
Tag % 2 == 0)
11909 IsIntegerValue =
true;
11910 else if (
Tag % 2 == 1)
11911 IsStringValue =
true;
11915 if (IsIntegerValue) {
11916 const MCExpr *ValueExpr;
11923 return Error(ValueExprLoc,
"expected numeric constant");
11924 IntegerValue =
CE->getValue();
11932 std::string EscapedValue;
11933 if (IsStringValue) {
11941 StringValue = EscapedValue;
11951 if (IsIntegerValue && IsStringValue) {
11953 getTargetStreamer().emitIntTextAttribute(
Tag, IntegerValue, StringValue);
11954 }
else if (IsIntegerValue)
11955 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
11956 else if (IsStringValue)
11957 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
11963bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11964 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11969 if (!getSTI().isCPUStringValid(CPU))
11970 return Error(L,
"Unknown CPU name");
11973 MCSubtargetInfo &STI = copySTI();
11975 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11976 FixModeAfterArchChange(WasThumb, L);
11983bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11984 SMLoc FPUNameLoc = getTok().getLoc();
11985 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11988 std::vector<StringRef> Features;
11990 return Error(FPUNameLoc,
"Unknown FPU name");
11992 MCSubtargetInfo &STI = copySTI();
11993 for (
auto Feature : Features)
11995 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11997 getTargetStreamer().emitFPU(ID);
12003bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
12007 if (UC.hasFnStart()) {
12008 Error(L,
".fnstart starts before the end of previous one");
12009 UC.emitFnStartLocNotes();
12016 getTargetStreamer().emitFnStart();
12018 UC.recordFnStart(L);
12024bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12028 if (!UC.hasFnStart())
12029 return Error(L,
".fnstart must precede .fnend directive");
12032 getTargetStreamer().emitFnEnd();
12040bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12044 UC.recordCantUnwind(L);
12046 if (check(!UC.hasFnStart(), L,
".fnstart must precede .cantunwind directive"))
12049 if (UC.hasHandlerData()) {
12050 Error(L,
".cantunwind can't be used with .handlerdata directive");
12051 UC.emitHandlerDataLocNotes();
12054 if (UC.hasPersonality()) {
12055 Error(L,
".cantunwind can't be used with .personality directive");
12056 UC.emitPersonalityLocNotes();
12060 getTargetStreamer().emitCantUnwind();
12066bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12067 MCAsmParser &Parser = getParser();
12068 bool HasExistingPersonality = UC.hasPersonality();
12072 return Error(L,
"unexpected input in .personality directive.");
12079 UC.recordPersonality(L);
12082 if (!UC.hasFnStart())
12083 return Error(L,
".fnstart must precede .personality directive");
12084 if (UC.cantUnwind()) {
12085 Error(L,
".personality can't be used with .cantunwind directive");
12086 UC.emitCantUnwindLocNotes();
12089 if (UC.hasHandlerData()) {
12090 Error(L,
".personality must precede .handlerdata directive");
12091 UC.emitHandlerDataLocNotes();
12094 if (HasExistingPersonality) {
12095 Error(L,
"multiple personality directives");
12096 UC.emitPersonalityLocNotes();
12100 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12101 getTargetStreamer().emitPersonality(PR);
12107bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12111 UC.recordHandlerData(L);
12113 if (!UC.hasFnStart())
12114 return Error(L,
".fnstart must precede .personality directive");
12115 if (UC.cantUnwind()) {
12116 Error(L,
".handlerdata can't be used with .cantunwind directive");
12117 UC.emitCantUnwindLocNotes();
12121 getTargetStreamer().emitHandlerData();
12127bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12128 MCAsmParser &Parser = getParser();
12130 if (check(!UC.hasFnStart(), L,
".fnstart must precede .setfp directive") ||
12131 check(UC.hasHandlerData(), L,
12132 ".setfp must precede .handlerdata directive"))
12137 MCRegister
FPReg = tryParseRegister();
12139 if (check(!
FPReg, FPRegLoc,
"frame pointer register expected") ||
12145 MCRegister
SPReg = tryParseRegister();
12146 if (check(!
SPReg, SPRegLoc,
"stack pointer register expected") ||
12147 check(
SPReg != ARM::SP &&
SPReg != UC.getFPReg(), SPRegLoc,
12148 "register should be either $sp or the latest fp register"))
12152 UC.saveFPReg(
FPReg);
12162 const MCExpr *OffsetExpr;
12165 if (getParser().parseExpression(OffsetExpr, EndLoc))
12166 return Error(ExLoc,
"malformed setfp offset");
12168 if (check(!CE, ExLoc,
"setfp offset must be an immediate"))
12182bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12183 MCAsmParser &Parser = getParser();
12185 if (!UC.hasFnStart())
12186 return Error(L,
".fnstart must precede .pad directive");
12187 if (UC.hasHandlerData())
12188 return Error(L,
".pad must precede .handlerdata directive");
12196 const MCExpr *OffsetExpr;
12199 if (getParser().parseExpression(OffsetExpr, EndLoc))
12200 return Error(ExLoc,
"malformed pad offset");
12203 return Error(ExLoc,
"pad offset must be an immediate");
12208 getTargetStreamer().emitPad(
CE->getValue());
12215bool ARMAsmParser::parseDirectiveRegSave(SMLoc L,
bool IsVector) {
12217 if (!UC.hasFnStart())
12218 return Error(L,
".fnstart must precede .save or .vsave directives");
12219 if (UC.hasHandlerData())
12220 return Error(L,
".save or .vsave must precede .handlerdata directive");
12226 if (parseRegisterList(
Operands,
true,
true) || parseEOL())
12228 ARMOperand &
Op = (ARMOperand &)*
Operands[0];
12229 if (!IsVector && !
Op.isRegList())
12230 return Error(L,
".save expects GPR registers");
12231 if (IsVector && !
Op.isDPRRegList())
12232 return Error(L,
".vsave expects DPR registers");
12234 getTargetStreamer().emitRegSave(
Op.getRegList(), IsVector);
12242bool ARMAsmParser::parseDirectiveInst(SMLoc Loc,
char Suffix) {
12258 return Error(Loc,
"width suffixes are invalid in ARM mode");
12261 auto parseOne = [&]() ->
bool {
12262 const MCExpr *Expr;
12263 if (getParser().parseExpression(Expr))
12267 return Error(Loc,
"expected constant expression");
12270 char CurSuffix = Suffix;
12273 if (
Value->getValue() > 0xffff)
12274 return Error(Loc,
"inst.n operand is too big, use inst.w instead");
12277 if (
Value->getValue() > 0xffffffff)
12278 return Error(Loc, StringRef(Suffix ?
"inst.w" :
"inst") +
12279 " operand is too big");
12283 if (
Value->getValue() < 0xe800)
12285 else if (
Value->getValue() >= 0xe8000000)
12288 return Error(Loc,
"cannot determine Thumb instruction size, "
12289 "use inst.n/inst.w instead");
12295 getTargetStreamer().emitInst(
Value->getValue(), CurSuffix);
12296 forwardITPosition();
12297 forwardVPTPosition();
12302 return Error(Loc,
"expected expression following directive");
12303 if (parseMany(parseOne))
12310bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12313 getTargetStreamer().emitCurrentConstantPool();
12317bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12318 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12324 getStreamer().initSections(getSTI());
12325 Section = getStreamer().getCurrentSectionOnly();
12328 assert(Section &&
"must have section to emit alignment");
12329 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12330 getStreamer().emitCodeAlignment(
Align(2), getSTI());
12332 getStreamer().emitValueToAlignment(
Align(2));
12339bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12340 MCAsmParser &Parser = getParser();
12341 bool HasExistingPersonality = UC.hasPersonality();
12343 const MCExpr *IndexExpression;
12349 UC.recordPersonalityIndex(L);
12351 if (!UC.hasFnStart()) {
12352 return Error(L,
".fnstart must precede .personalityindex directive");
12354 if (UC.cantUnwind()) {
12355 Error(L,
".personalityindex cannot be used with .cantunwind");
12356 UC.emitCantUnwindLocNotes();
12359 if (UC.hasHandlerData()) {
12360 Error(L,
".personalityindex must precede .handlerdata directive");
12361 UC.emitHandlerDataLocNotes();
12364 if (HasExistingPersonality) {
12365 Error(L,
"multiple personality directives");
12366 UC.emitPersonalityLocNotes();
12372 return Error(IndexLoc,
"index must be a constant number");
12374 return Error(IndexLoc,
12375 "personality routine index should be in range [0-3]");
12377 getTargetStreamer().emitPersonalityIndex(
CE->getValue());
12383bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12384 MCAsmParser &Parser = getParser();
12385 int64_t StackOffset;
12386 const MCExpr *OffsetExpr;
12387 SMLoc OffsetLoc = getLexer().
getLoc();
12389 if (!UC.hasFnStart())
12390 return Error(L,
".fnstart must precede .unwind_raw directives");
12391 if (getParser().parseExpression(OffsetExpr))
12392 return Error(OffsetLoc,
"expected expression");
12396 return Error(OffsetLoc,
"offset must be a constant");
12398 StackOffset =
CE->getValue();
12405 auto parseOne = [&]() ->
bool {
12406 const MCExpr *OE =
nullptr;
12407 SMLoc OpcodeLoc = getLexer().getLoc();
12410 OpcodeLoc,
"expected opcode expression"))
12414 return Error(OpcodeLoc,
"opcode value must be a constant");
12415 const int64_t Opcode = OC->
getValue();
12416 if (Opcode & ~0xff)
12417 return Error(OpcodeLoc,
"invalid opcode");
12423 SMLoc OpcodeLoc = getLexer().getLoc();
12425 return Error(OpcodeLoc,
"expected opcode expression");
12426 if (parseMany(parseOne))
12429 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12435bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12436 MCAsmParser &Parser = getParser();
12439 return TokError(
"expected variable after '.tlsdescseq' directive");
12449 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12455bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12456 MCAsmParser &Parser = getParser();
12457 if (!UC.hasFnStart())
12458 return Error(L,
".fnstart must precede .movsp directives");
12459 if (UC.getFPReg() != ARM::SP)
12460 return Error(L,
"unexpected .movsp directive");
12463 MCRegister
SPReg = tryParseRegister();
12465 return Error(SPRegLoc,
"register expected");
12467 return Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
12474 const MCExpr *OffsetExpr;
12478 return Error(OffsetLoc,
"malformed offset expression");
12482 return Error(OffsetLoc,
"offset must be an immediate constant");
12491 UC.saveFPReg(
SPReg);
12498bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12499 MCAsmParser &Parser = getParser();
12501 return Error(getLexer().getLoc(),
"unexpected token");
12509 if (ID == ARM::ArchKind::INVALID)
12510 return Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
12514 getTargetStreamer().emitObjectArch(ID);
12520bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12525 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12526 assert(Section &&
"must have section to emit alignment");
12527 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12528 getStreamer().emitCodeAlignment(
Align(4), getSTI(), 0);
12530 getStreamer().emitValueToAlignment(
Align(4), 0, 1, 0);
12538bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12539 MCAsmParser &Parser = getParser();
12543 "expected identifier after '.thumb_set'") ||
12548 const MCExpr *
Value;
12550 Parser, Sym,
Value))
12553 getTargetStreamer().emitThumbSet(Sym,
Value);
12560bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L,
bool Wide) {
12562 if (parseImmExpr(
Size))
12564 getTargetStreamer().emitARMWinCFIAllocStack(
Size, Wide);
12571bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L,
bool Wide) {
12574 if (parseRegisterList(
Operands) || parseEOL())
12576 ARMOperand &
Op = (ARMOperand &)*
Operands[0];
12577 if (!
Op.isRegList())
12578 return Error(L,
".seh_save_regs{_w} expects GPR registers");
12579 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12581 for (
size_t i = 0; i < RegList.
size(); ++i) {
12582 unsigned Reg =
MRI->getEncodingValue(RegList[i]);
12586 return Error(L,
".seh_save_regs{_w} can't include SP");
12587 assert(
Reg < 16U &&
"Register out of range");
12588 unsigned Bit = (1u <<
Reg);
12591 if (!Wide && (Mask & 0x1f00) != 0)
12593 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12594 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12600bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12601 MCRegister
Reg = tryParseRegister();
12603 return Error(L,
"expected GPR");
12605 if (Index > 14 || Index == 13)
12606 return Error(L,
"invalid register for .seh_save_sp");
12607 getTargetStreamer().emitARMWinCFISaveSP(Index);
12613bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12616 if (parseRegisterList(
Operands) || parseEOL())
12618 ARMOperand &
Op = (ARMOperand &)*
Operands[0];
12619 if (!
Op.isDPRRegList())
12620 return Error(L,
".seh_save_fregs expects DPR registers");
12621 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12623 for (
size_t i = 0; i < RegList.
size(); ++i) {
12624 unsigned Reg =
MRI->getEncodingValue(RegList[i]);
12625 assert(
Reg < 32U &&
"Register out of range");
12626 unsigned Bit = (1u <<
Reg);
12631 return Error(L,
".seh_save_fregs missing registers");
12633 unsigned First = 0;
12634 while ((Mask & 1) == 0) {
12638 if (((Mask + 1) & Mask) != 0)
12640 ".seh_save_fregs must take a contiguous range of registers");
12642 while ((Mask & 2) != 0) {
12647 return Error(L,
".seh_save_fregs must be all d0-d15 or d16-d31");
12648 getTargetStreamer().emitARMWinCFISaveFRegs(
First,
Last);
12654bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12656 if (parseImmExpr(
Offset))
12658 getTargetStreamer().emitARMWinCFISaveLR(
Offset);
12665bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L,
bool Fragment) {
12666 getTargetStreamer().emitARMWinCFIPrologEnd(
Fragment);
12673bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L,
bool Wide) {
12674 getTargetStreamer().emitARMWinCFINop(Wide);
12681bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L,
bool Condition) {
12684 MCAsmParser &Parser = getParser();
12686 const AsmToken &Tok = Parser.
getTok();
12688 return Error(S,
".seh_startepilogue_cond missing condition");
12691 return Error(S,
"invalid condition");
12695 getTargetStreamer().emitARMWinCFIEpilogStart(
CC);
12701bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12702 getTargetStreamer().emitARMWinCFIEpilogEnd();
12708bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12709 unsigned Opcode = 0;
12712 if (parseImmExpr(Byte))
12714 if (Byte > 0xff || Byte < 0)
12715 return Error(L,
"Invalid byte value in .seh_custom");
12716 if (Opcode > 0x00ffffff)
12717 return Error(L,
"Too many bytes in .seh_custom");
12720 Opcode = (Opcode << 8) | Byte;
12722 getTargetStreamer().emitARMWinCFICustom(Opcode);
12734#define GET_REGISTER_MATCHER
12735#define GET_SUBTARGET_FEATURE_NAME
12736#define GET_MATCHER_IMPLEMENTATION
12737#define GET_MNEMONIC_SPELL_CHECKER
12738#include "ARMGenAsmMatcher.inc"
12744ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12745 switch (MatchError) {
12748 return hasV8Ops() ?
"operand must be a register in range [r0, r14]"
12749 :
"operand must be a register in range [r0, r12] or r14";
12752 return hasD32() ?
"operand must be a register in range [d0, d31]"
12753 :
"operand must be a register in range [d0, d15]";
12754 case Match_DPR_RegList:
12755 return hasD32() ?
"operand must be a list of registers in range [d0, d31]"
12756 :
"operand must be a list of registers in range [d0, d15]";
12760 return getMatchKindDiag(MatchError);
12768ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12769 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12783 std::multimap<unsigned, unsigned> OperandMissesSeen;
12784 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12785 bool ReportedTooFewOperands =
false;
12791 for (NearMissInfo &
I :
reverse(NearMissesIn)) {
12792 switch (
I.getKind()) {
12795 ((ARMOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
12796 const char *OperandDiag =
12797 getCustomOperandDiag((ARMMatchResultTy)
I.getOperandError());
12804 unsigned DupCheckMatchClass = OperandDiag ?
I.getOperandClass() : ~0
U;
12805 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
12806 if (std::any_of(PrevReports.first, PrevReports.second,
12807 [DupCheckMatchClass](
12808 const std::pair<unsigned, unsigned> Pair) {
12809 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12810 return Pair.second == DupCheckMatchClass;
12812 return isSubclass((MatchClassKind)DupCheckMatchClass,
12813 (MatchClassKind)Pair.second);
12816 OperandMissesSeen.insert(
12817 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
12819 NearMissMessage Message;
12820 Message.Loc = OperandLoc;
12822 Message.Message = OperandDiag;
12823 }
else if (
I.getOperandClass() == InvalidMatchClass) {
12824 Message.Message =
"too many operands for instruction";
12826 Message.Message =
"invalid operand for instruction";
12828 dbgs() <<
"Missing diagnostic string for operand class "
12829 << getMatchClassName((MatchClassKind)
I.getOperandClass())
12830 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
12831 <<
", opcode " << MII.getName(
I.getOpcode()) <<
"\n");
12837 const FeatureBitset &MissingFeatures =
I.getFeatures();
12839 if (FeatureMissesSeen.
count(MissingFeatures))
12841 FeatureMissesSeen.
insert(MissingFeatures);
12845 if (MissingFeatures.
test(Feature_IsARMBit) && !hasARM())
12849 if (
isThumb() && MissingFeatures.
test(Feature_IsARMBit) &&
12850 MissingFeatures.
count() > 1)
12852 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumbBit) &&
12853 MissingFeatures.
count() > 1)
12855 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumb2Bit) &&
12856 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12857 Feature_IsThumbBit})).any())
12859 if (isMClass() && MissingFeatures.
test(Feature_HasNEONBit))
12862 NearMissMessage Message;
12863 Message.Loc = IDLoc;
12864 raw_svector_ostream OS(Message.Message);
12866 OS <<
"instruction requires:";
12867 for (
unsigned Feature : MissingFeatures)
12875 NearMissMessage Message;
12876 Message.Loc = IDLoc;
12877 switch (
I.getPredicateError()) {
12878 case Match_RequiresNotITBlock:
12879 Message.Message =
"flag setting instruction only valid outside IT block";
12881 case Match_RequiresITBlock:
12882 Message.Message =
"instruction only valid inside IT block";
12884 case Match_RequiresV6:
12885 Message.Message =
"instruction variant requires ARMv6 or later";
12887 case Match_RequiresThumb2:
12888 Message.Message =
"instruction variant requires Thumb2";
12890 case Match_RequiresV8:
12891 Message.Message =
"instruction variant requires ARMv8 or later";
12893 case Match_RequiresFlagSetting:
12894 Message.Message =
"no flag-preserving variant of this instruction available";
12896 case Match_InvalidTiedOperand: {
12897 ARMOperand &
Op =
static_cast<ARMOperand &
>(*
Operands[0]);
12898 if (
Op.isToken() &&
Op.getToken() ==
"mul") {
12899 Message.Message =
"destination register must match a source register";
12900 Message.Loc =
Operands[MnemonicOpsEndInd]->getStartLoc();
12906 case Match_InvalidOperand:
12907 Message.Message =
"invalid operand for instruction";
12917 if (!ReportedTooFewOperands) {
12918 SMLoc EndLoc = ((ARMOperand &)*
Operands.back()).getEndLoc();
12920 EndLoc, StringRef(
"too few operands for instruction")});
12921 ReportedTooFewOperands =
true;
12933void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12936 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
12941 Error(IDLoc,
"invalid instruction");
12942 }
else if (
Messages.size() == 1) {
12944 Error(Messages[0].Loc, Messages[0].Message);
12948 Error(IDLoc,
"invalid instruction, any one of the following would fix this:");
12949 for (
auto &M : Messages) {
12955bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12959 static const struct {
12961 const FeatureBitset ArchCheck;
12962 const FeatureBitset Features;
12964 {
ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12966 {Feature_HasV8Bit},
12967 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12969 {Feature_HasV8Bit},
12970 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12972 {Feature_HasV8Bit},
12973 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12975 {Feature_HasV8_1MMainlineBit},
12976 {ARM::HasMVEFloatOps}},
12978 {Feature_HasV8Bit},
12979 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12981 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12982 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12984 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12987 {Feature_HasV8Bit},
12988 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12989 {
ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12991 {
ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12993 {Feature_HasV8_2aBit},
12994 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12995 {
ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12996 {
ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12997 {
ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
13005 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
13008 return Error(ExtLoc,
"unknown architectural extension: " + Name);
13010 for (
const auto &Extension : Extensions) {
13015 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
13018 return Error(ExtLoc,
"architectural extension '" + Name +
13020 "allowed for the current base architecture");
13022 MCSubtargetInfo &STI = copySTI();
13023 if (EnableFeature) {
13028 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
13029 setAvailableFeatures(Features);
13037bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13039 MCAsmParser &Parser = getParser();
13042 return Error(getLexer().getLoc(),
"expected architecture extension name");
13051 if (Name ==
"nocrypto") {
13052 enableArchExtFeature(
"nosha2", ExtLoc);
13053 enableArchExtFeature(
"noaes", ExtLoc);
13056 if (enableArchExtFeature(Name, ExtLoc))
13059 return Error(ExtLoc,
"unknown architectural extension: " + Name);
13064unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13066 ARMOperand &
Op =
static_cast<ARMOperand &
>(AsmOp);
13075 if (
CE->getValue() == 0)
13076 return Match_Success;
13081 if (
CE->getValue() == 8)
13082 return Match_Success;
13087 if (
CE->getValue() == 16)
13088 return Match_Success;
13092 const MCExpr *SOExpr =
Op.getImm();
13094 if (!SOExpr->evaluateAsAbsolute(
Value))
13095 return Match_Success;
13096 assert((
Value >= std::numeric_limits<int32_t>::min() &&
13097 Value <= std::numeric_limits<uint32_t>::max()) &&
13098 "expression value must be representable in 32 bits");
13102 if (hasV8Ops() &&
Op.isReg() &&
Op.getReg() == ARM::SP)
13103 return Match_Success;
13106 return Match_InvalidOperand;
13109bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13110 StringRef ExtraToken) {
13114 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13115 (Mnemonic.
starts_with(
"vldrh") && Mnemonic !=
"vldrhi") ||
13117 !(ExtraToken ==
".f16" || ExtraToken ==
".32" || ExtraToken ==
".16" ||
13118 ExtraToken ==
".8")) ||
13119 (Mnemonic.
starts_with(
"vrint") && Mnemonic !=
"vrintr") ||
13120 (Mnemonic.
starts_with(
"vstrh") && Mnemonic !=
"vstrhi"))
13123 const char *predicable_prefixes[] = {
13124 "vabav",
"vabd",
"vabs",
"vadc",
"vadd",
13125 "vaddlv",
"vaddv",
"vand",
"vbic",
"vbrsr",
13126 "vcadd",
"vcls",
"vclz",
"vcmla",
"vcmp",
13127 "vcmul",
"vctp",
"vcvt",
"vddup",
"vdup",
13128 "vdwdup",
"veor",
"vfma",
"vfmas",
"vfms",
13129 "vhadd",
"vhcadd",
"vhsub",
"vidup",
"viwdup",
13130 "vldrb",
"vldrd",
"vldrw",
"vmax",
"vmaxa",
13131 "vmaxav",
"vmaxnm",
"vmaxnma",
"vmaxnmav",
"vmaxnmv",
13132 "vmaxv",
"vmin",
"vminav",
"vminnm",
"vminnmav",
13133 "vminnmv",
"vminv",
"vmla",
"vmladav",
"vmlaldav",
13134 "vmlalv",
"vmlas",
"vmlav",
"vmlsdav",
"vmlsldav",
13135 "vmovlb",
"vmovlt",
"vmovnb",
"vmovnt",
"vmul",
13136 "vmvn",
"vneg",
"vorn",
"vorr",
"vpnot",
13137 "vpsel",
"vqabs",
"vqadd",
"vqdmladh",
"vqdmlah",
13138 "vqdmlash",
"vqdmlsdh",
"vqdmulh",
"vqdmull",
"vqmovn",
13139 "vqmovun",
"vqneg",
"vqrdmladh",
"vqrdmlah",
"vqrdmlash",
13140 "vqrdmlsdh",
"vqrdmulh",
"vqrshl",
"vqrshrn",
"vqrshrun",
13141 "vqshl",
"vqshrn",
"vqshrun",
"vqsub",
"vrev16",
13142 "vrev32",
"vrev64",
"vrhadd",
"vrmlaldavh",
"vrmlalvh",
13143 "vrmlsldavh",
"vrmulh",
"vrshl",
"vrshr",
"vrshrn",
13144 "vsbc",
"vshl",
"vshlc",
"vshll",
"vshr",
13145 "vshrn",
"vsli",
"vsri",
"vstrb",
"vstrd",
13148 return any_of(predicable_prefixes, [&Mnemonic](
const char *prefix) {
13153std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13154 return ARMOperand::CreateCondCode(
ARMCC::AL, SMLoc(), *
this);
13157std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13158 return ARMOperand::CreateCCOut(0, SMLoc(), *
this);
13161std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13162 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)
AMDGPU Reserve WWM Registers
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)
static constexpr Value * getValue(Ty &ValueOrUse)
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
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
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")))
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Implements a dense probed hash-table based set.
Base class for user error types.
Container class for subtarget features.
constexpr bool test(unsigned I) const
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range={})=0
Emit a note at the location L, with the message Msg.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ Constant
Constant expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
LLVM_ABI bool hasDefOfPhysReg(const MCInst &MI, MCRegister Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
bool isReturn() const
Return true if the instruction is a return.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
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.
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()
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
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)
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.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
LLVM_ABI bool parseAssignmentExpression(StringRef Name, bool allow_redef, MCAsmParser &Parser, MCSymbol *&Symbol, const MCExpr *&Value)
Parse a value expression and return whether it can be assigned to a symbol with the given name.
@ CE
Windows NT (Windows on ARM)
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
static const char * ARMVPTPredToString(ARMVCC::VPTCodes CC)
constexpr T rotr(T V, int R)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
@ Load
The value being inserted comes from a load (InsertElement only).
Target & getTheThumbBETarget()
static unsigned ARMCondCodeFromString(StringRef CC)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
@ Never
Never set the bit.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool IsCPSRDead< MCInst >(const MCInst *Instr)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
static bool isValidCoprocessorNumber(unsigned Num, const FeatureBitset &featureBits)
isValidCoprocessorNumber - decide whether an explicit coprocessor number is legal in generic instruct...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
static unsigned ARMVectorCondCodeFromString(StringRef CC)
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
@ Always
Always emit .debug_str_offsets talbes as DWARF64 for testing.
Target & getTheARMLETarget()
Target & getTheARMBETarget()
Target & getTheThumbLETarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...