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()) {
308 for (
const MCInst &Inst : PendingConditionalInsts) {
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);
496 bool parseDirectiveSEHPrologEnd(
SMLoc L,
bool Fragment);
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);
3655 static std::unique_ptr<ARMOperand> CreateVPTPred(
ARMVCC::VPTCodes CC, SMLoc S,
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);
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");
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");
4703 return Error(AfterMinusLoc,
"bad range in register list");
4706 while (
Reg != EndReg) {
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);
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");
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");
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));
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);
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"))
6477 Out =
Value->getValue();
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())
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();
7445 MCRegister Reg2 = Op2.getReg();
7449 return Error(Op2.getStartLoc(),
7450 IsLoad ?
"destination operands must be sequential"
7451 :
"source operands must be sequential");
7457 IsLoad ?
"destination operands must start start at an even register"
7458 :
"source operands must start start at an even register");
7461 Reg1, ARM::gsub_0, &(MRI->
getRegClass(ARM::GPRPairRegClassID)));
7462 Operands[Idx] = ARMOperand::CreateReg(NewReg, Op1.getStartLoc(),
7463 Op2.getEndLoc(), *
this);
7473 if (isThumbTwo() && Mnemonic ==
"sub" && 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))
7828 case ARM::STR_PRE_IMM:
7829 case ARM::STR_PRE_REG:
7830 case ARM::t2STR_PRE:
7831 case ARM::STR_POST_IMM:
7832 case ARM::STR_POST_REG:
7833 case ARM::t2STR_POST:
7835 case ARM::t2STRH_PRE:
7836 case ARM::STRH_POST:
7837 case ARM::t2STRH_POST:
7838 case ARM::STRB_PRE_IMM:
7839 case ARM::STRB_PRE_REG:
7840 case ARM::t2STRB_PRE:
7841 case ARM::STRB_POST_IMM:
7842 case ARM::STRB_POST_REG:
7843 case ARM::t2STRB_POST: {
7849 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
7850 "source register and base register can't be identical");
7853 case ARM::t2LDR_PRE_imm:
7854 case ARM::t2LDR_POST_imm:
7855 case ARM::t2STR_PRE_imm:
7856 case ARM::t2STR_POST_imm: {
7863 "destination register and base register can't be identical");
7864 if (Inst.
getOpcode() == ARM::t2LDR_POST_imm ||
7865 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7867 if (
Imm > 255 ||
Imm < -255)
7868 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7869 "operand must be in range [-255, 255]");
7871 if (Inst.
getOpcode() == ARM::t2STR_PRE_imm ||
7872 Inst.
getOpcode() == ARM::t2STR_POST_imm) {
7875 "operand must be a register in range [r0, r14]");
7881 case ARM::t2LDRB_OFFSET_imm:
7882 case ARM::t2LDRB_PRE_imm:
7883 case ARM::t2LDRB_POST_imm:
7884 case ARM::t2STRB_OFFSET_imm:
7885 case ARM::t2STRB_PRE_imm:
7886 case ARM::t2STRB_POST_imm: {
7887 if (Inst.
getOpcode() == ARM::t2LDRB_POST_imm ||
7888 Inst.
getOpcode() == ARM::t2STRB_POST_imm ||
7889 Inst.
getOpcode() == ARM::t2LDRB_PRE_imm ||
7890 Inst.
getOpcode() == ARM::t2STRB_PRE_imm) {
7892 if (
Imm > 255 ||
Imm < -255)
7893 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7894 "operand must be in range [-255, 255]");
7895 }
else if (Inst.
getOpcode() == ARM::t2LDRB_OFFSET_imm ||
7896 Inst.
getOpcode() == ARM::t2STRB_OFFSET_imm) {
7898 if (
Imm > 0 ||
Imm < -255)
7899 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7900 "operand must be in range [0, 255] with a negative sign");
7904 "if operand is PC, should call the LDRB (literal)");
7909 case ARM::t2LDRH_OFFSET_imm:
7910 case ARM::t2LDRH_PRE_imm:
7911 case ARM::t2LDRH_POST_imm:
7912 case ARM::t2STRH_OFFSET_imm:
7913 case ARM::t2STRH_PRE_imm:
7914 case ARM::t2STRH_POST_imm: {
7915 if (Inst.
getOpcode() == ARM::t2LDRH_POST_imm ||
7916 Inst.
getOpcode() == ARM::t2STRH_POST_imm ||
7917 Inst.
getOpcode() == ARM::t2LDRH_PRE_imm ||
7918 Inst.
getOpcode() == ARM::t2STRH_PRE_imm) {
7920 if (
Imm > 255 ||
Imm < -255)
7921 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7922 "operand must be in range [-255, 255]");
7923 }
else if (Inst.
getOpcode() == ARM::t2LDRH_OFFSET_imm ||
7924 Inst.
getOpcode() == ARM::t2STRH_OFFSET_imm) {
7926 if (
Imm > 0 ||
Imm < -255)
7927 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7928 "operand must be in range [0, 255] with a negative sign");
7932 "if operand is PC, should call the LDRH (literal)");
7937 case ARM::t2LDRSB_OFFSET_imm:
7938 case ARM::t2LDRSB_PRE_imm:
7939 case ARM::t2LDRSB_POST_imm: {
7940 if (Inst.
getOpcode() == ARM::t2LDRSB_POST_imm ||
7941 Inst.
getOpcode() == ARM::t2LDRSB_PRE_imm) {
7943 if (
Imm > 255 ||
Imm < -255)
7944 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7945 "operand must be in range [-255, 255]");
7946 }
else if (Inst.
getOpcode() == ARM::t2LDRSB_OFFSET_imm) {
7948 if (
Imm > 0 ||
Imm < -255)
7949 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7950 "operand must be in range [0, 255] with a negative sign");
7953 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7954 "if operand is PC, should call the LDRH (literal)");
7959 case ARM::t2LDRSH_OFFSET_imm:
7960 case ARM::t2LDRSH_PRE_imm:
7961 case ARM::t2LDRSH_POST_imm: {
7962 if (Inst.
getOpcode() == ARM::t2LDRSH_POST_imm ||
7963 Inst.
getOpcode() == ARM::t2LDRSH_PRE_imm) {
7965 if (
Imm > 255 ||
Imm < -255)
7966 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7967 "operand must be in range [-255, 255]");
7968 }
else if (Inst.
getOpcode() == ARM::t2LDRSH_OFFSET_imm) {
7970 if (
Imm > 0 ||
Imm < -255)
7971 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
7972 "operand must be in range [0, 255] with a negative sign");
7976 "if operand is PC, should call the LDRH (literal)");
7981 case ARM::LDR_PRE_IMM:
7982 case ARM::LDR_PRE_REG:
7983 case ARM::t2LDR_PRE:
7984 case ARM::LDR_POST_IMM:
7985 case ARM::LDR_POST_REG:
7986 case ARM::t2LDR_POST:
7988 case ARM::t2LDRH_PRE:
7989 case ARM::LDRH_POST:
7990 case ARM::t2LDRH_POST:
7991 case ARM::LDRSH_PRE:
7992 case ARM::t2LDRSH_PRE:
7993 case ARM::LDRSH_POST:
7994 case ARM::t2LDRSH_POST:
7995 case ARM::LDRB_PRE_IMM:
7996 case ARM::LDRB_PRE_REG:
7997 case ARM::t2LDRB_PRE:
7998 case ARM::LDRB_POST_IMM:
7999 case ARM::LDRB_POST_REG:
8000 case ARM::t2LDRB_POST:
8001 case ARM::LDRSB_PRE:
8002 case ARM::t2LDRSB_PRE:
8003 case ARM::LDRSB_POST:
8004 case ARM::t2LDRSB_POST: {
8011 "destination register and base register can't be identical");
8015 case ARM::MVE_VLDRBU8_rq:
8016 case ARM::MVE_VLDRBU16_rq:
8017 case ARM::MVE_VLDRBS16_rq:
8018 case ARM::MVE_VLDRBU32_rq:
8019 case ARM::MVE_VLDRBS32_rq:
8020 case ARM::MVE_VLDRHU16_rq:
8021 case ARM::MVE_VLDRHU16_rq_u:
8022 case ARM::MVE_VLDRHU32_rq:
8023 case ARM::MVE_VLDRHU32_rq_u:
8024 case ARM::MVE_VLDRHS32_rq:
8025 case ARM::MVE_VLDRHS32_rq_u:
8026 case ARM::MVE_VLDRWU32_rq:
8027 case ARM::MVE_VLDRWU32_rq_u:
8028 case ARM::MVE_VLDRDU64_rq:
8029 case ARM::MVE_VLDRDU64_rq_u:
8030 case ARM::MVE_VLDRWU32_qi:
8031 case ARM::MVE_VLDRWU32_qi_pre:
8032 case ARM::MVE_VLDRDU64_qi:
8033 case ARM::MVE_VLDRDU64_qi_pre: {
8035 unsigned QdIdx = 0, QmIdx = 2;
8036 bool QmIsPointer =
false;
8038 case ARM::MVE_VLDRWU32_qi:
8039 case ARM::MVE_VLDRDU64_qi:
8043 case ARM::MVE_VLDRWU32_qi_pre:
8044 case ARM::MVE_VLDRDU64_qi_pre:
8055 Twine(
"destination vector register and vector ") +
8056 (QmIsPointer ?
"pointer" :
"offset") +
8057 " register can't be identical");
8069 if (Widthm1 >= 32 - LSB)
8070 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8071 "bitfield width must be in range [1,32-lsb]");
8083 bool HasWritebackToken =
8084 (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8086 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8089 bool ListContainsBase;
8094 "registers must be in range r0-r7");
8096 if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
8099 "writeback operator '!' expected");
8102 if (ListContainsBase && HasWritebackToken)
8103 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8104 "writeback operator '!' not allowed when base register "
8105 "in register list");
8107 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8111 case ARM::LDMIA_UPD:
8112 case ARM::LDMDB_UPD:
8113 case ARM::LDMIB_UPD:
8114 case ARM::LDMDA_UPD:
8121 "writeback register not allowed in register list");
8125 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8130 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8133 case ARM::t2LDMIA_UPD:
8134 case ARM::t2LDMDB_UPD:
8135 case ARM::t2STMIA_UPD:
8136 case ARM::t2STMDB_UPD:
8139 "writeback register not allowed in register list");
8141 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
8142 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8145 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 3))
8150 case ARM::sysLDMIA_UPD:
8151 case ARM::sysLDMDA_UPD:
8152 case ARM::sysLDMDB_UPD:
8153 case ARM::sysLDMIB_UPD:
8155 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8156 "writeback register only allowed on system LDM "
8157 "if PC in register-list");
8159 case ARM::sysSTMIA_UPD:
8160 case ARM::sysSTMDA_UPD:
8161 case ARM::sysSTMDB_UPD:
8162 case ARM::sysSTMIB_UPD:
8164 "system STM cannot have writeback register");
8169 bool ListContainsBase;
8171 ListContainsBase) &&
8174 "registers must be in range r0-r7 or pc");
8175 if (validatetLDMRegList(Inst,
Operands, MnemonicOpsEndInd, 2, !isMClass()))
8180 bool ListContainsBase;
8182 ListContainsBase) &&
8185 "registers must be in range r0-r7 or lr");
8186 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 2))
8190 case ARM::tSTMIA_UPD: {
8191 bool ListContainsBase, InvalidLowList;
8193 0, ListContainsBase);
8194 if (InvalidLowList && !isThumbTwo())
8195 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8196 "registers must be in range r0-r7");
8200 if (InvalidLowList && ListContainsBase)
8202 "writeback operator '!' not allowed when base register "
8203 "in register list");
8205 if (validatetSTMRegList(Inst,
Operands, MnemonicOpsEndInd, 4))
8212 if (!isThumbTwo() &&
8214 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8215 "source register must be the same as destination");
8225 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8226 "source register must be sp if destination is sp");
8231 if (!(
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd]))
8232 .isSignedOffset<11, 1>())
8234 "branch target out of range");
8237 int op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8238 : MnemonicOpsEndInd + 1;
8239 ARMOperand &Operand =
static_cast<ARMOperand &
>(*
Operands[
op]);
8242 !Operand.isSignedOffset<24, 1>())
8243 return Error(
Operands[
op]->getStartLoc(),
"branch target out of range");
8248 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8249 .isSignedOffset<8, 1>())
8251 "branch target out of range");
8254 int Op = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8255 : MnemonicOpsEndInd + 1;
8256 if (!
static_cast<ARMOperand &
>(*
Operands[
Op]).isSignedOffset<20, 1>())
8257 return Error(
Operands[
Op]->getStartLoc(),
"branch target out of range");
8262 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8263 .isUnsignedOffset<6, 1>())
8264 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8265 "branch target out of range");
8271 case ARM::t2MOVTi16:
8279 int i = (
Operands[MnemonicOpsEndInd]->isImm()) ? MnemonicOpsEndInd
8280 : MnemonicOpsEndInd + 1;
8281 ARMOperand &
Op =
static_cast<ARMOperand &
>(*
Operands[i]);
8282 const MCExpr *
E =
Op.getImm();
8286 if (!ARM16Expr || (ARM16Expr->getSpecifier() !=
ARM::S_HI16 &&
8290 "immediate expression for mov requires :lower16: or :upper16");
8294 int i = (
Operands[MnemonicOpsEndInd + 1]->isImm()) ? MnemonicOpsEndInd + 1
8295 : MnemonicOpsEndInd + 2;
8298 return Error(
Op.getStartLoc(),
8299 "Immediate expression for Thumb adds requires :lower0_7:,"
8300 " :lower8_15:, :upper0_7: or :upper8_15:");
8304 MCParsedAsmOperand &
Op = *
Operands[MnemonicOpsEndInd + 1];
8306 return Error(
Op.getStartLoc(),
8307 "Immediate expression for Thumb movs requires :lower0_7:,"
8308 " :lower8_15:, :upper0_7: or :upper8_15:");
8317 if (Imm8 == 0x10 && Pred !=
ARMCC::AL && hasRAS())
8318 return Error(
Operands[1]->getStartLoc(),
"instruction 'esb' is not "
8319 "predicable, but condition "
8322 return Error(
Operands[1]->getStartLoc(),
"instruction 'csdb' is not "
8323 "predicable, but condition "
8331 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8332 .isUnsignedOffset<4, 1>() ||
8335 "branch location out of range or not a multiple of 2");
8338 if (Opcode == ARM::t2BFi) {
8339 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8340 .isSignedOffset<16, 1>())
8342 "branch target out of range or not a multiple of 2");
8343 }
else if (Opcode == ARM::t2BFLi) {
8344 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8345 .isSignedOffset<18, 1>())
8347 "branch target out of range or not a multiple of 2");
8352 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd])
8353 .isUnsignedOffset<4, 1>() ||
8356 "branch location out of range or not a multiple of 2");
8358 if (!
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8359 .isSignedOffset<16, 1>())
8360 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8361 "branch target out of range or not a multiple of 2");
8364 "branch location and else branch target should either both be "
8365 "immediates or both labels");
8369 if (Diff != 4 && Diff != 2)
8372 "else branch target must be 2 or 4 greater than the branch location");
8379 !getARMMCRegisterClass(ARM::GPRwithAPSRnospRegClassID)
8382 "invalid register in register list. Valid registers are "
8383 "r0-r12, lr/r14 and APSR.");
8400 "instruction 'ssbb' is not predicable, but condition code "
8404 "instruction 'pssbb' is not predicable, but condition code "
8408 case ARM::VMOVRRS: {
8413 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8414 "source operands must be sequential");
8417 case ARM::VMOVSRR: {
8423 "destination operands must be sequential");
8427 case ARM::VSTMDIA: {
8429 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
8430 auto &RegList =
Op.getRegList();
8431 if (RegList.size() < 1 || RegList.size() > 16)
8432 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8433 "list of registers must be at least 1 and at most 16");
8436 case ARM::MVE_VQDMULLs32bh:
8437 case ARM::MVE_VQDMULLs32th:
8438 case ARM::MVE_VCMULf32:
8439 case ARM::MVE_VMULLBs32:
8440 case ARM::MVE_VMULLTs32:
8441 case ARM::MVE_VMULLBu32:
8442 case ARM::MVE_VMULLTu32: {
8446 "Qd register and Qn register can't be identical");
8451 "Qd register and Qm register can't be identical");
8455 case ARM::MVE_VREV64_8:
8456 case ARM::MVE_VREV64_16:
8457 case ARM::MVE_VREV64_32:
8458 case ARM::MVE_VQDMULL_qr_s32bh:
8459 case ARM::MVE_VQDMULL_qr_s32th: {
8463 "Qd register and Qn register can't be identical");
8467 case ARM::MVE_VCADDi32:
8468 case ARM::MVE_VCADDf32:
8469 case ARM::MVE_VHCADDs32: {
8473 "Qd register and Qm register can't be identical");
8477 case ARM::MVE_VMOV_rr_q: {
8480 return Error(
Operands[MnemonicOpsEndInd + 2]->getStartLoc(),
8481 "Q-registers must be the same");
8482 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8483 .getVectorIndex() !=
8484 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 5])
8487 return Error(
Operands[MnemonicOpsEndInd + 3]->getStartLoc(),
8488 "Q-register indexes must be 2 and 0 or 3 and 1");
8491 case ARM::MVE_VMOV_q_rr: {
8495 "Q-registers must be the same");
8496 if (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
8497 .getVectorIndex() !=
8498 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 3])
8501 return Error(
Operands[MnemonicOpsEndInd + 1]->getStartLoc(),
8502 "Q-register indexes must be 2 and 0 or 3 and 1");
8505 case ARM::MVE_SQRSHR:
8506 case ARM::MVE_UQRSHL: {
8510 "Rda register and Rm register can't be identical");
8531 case ARM::t2SMLALBB:
8532 case ARM::t2SMLALBT:
8534 case ARM::t2SMLALDX:
8535 case ARM::t2SMLALTB:
8536 case ARM::t2SMLALTT:
8538 case ARM::t2SMLSLDX:
8539 case ARM::t2SMULL: {
8544 "unpredictable instruction, RdHi and RdLo must be different");
8552 case ARM::CDE_CX1DA:
8556 case ARM::CDE_CX2DA:
8560 case ARM::CDE_CX3DA:
8561 case ARM::CDE_VCX1_vec:
8562 case ARM::CDE_VCX1_fpsp:
8563 case ARM::CDE_VCX1_fpdp:
8564 case ARM::CDE_VCX1A_vec:
8565 case ARM::CDE_VCX1A_fpsp:
8566 case ARM::CDE_VCX1A_fpdp:
8567 case ARM::CDE_VCX2_vec:
8568 case ARM::CDE_VCX2_fpsp:
8569 case ARM::CDE_VCX2_fpdp:
8570 case ARM::CDE_VCX2A_vec:
8571 case ARM::CDE_VCX2A_fpsp:
8572 case ARM::CDE_VCX2A_fpdp:
8573 case ARM::CDE_VCX3_vec:
8574 case ARM::CDE_VCX3_fpsp:
8575 case ARM::CDE_VCX3_fpdp:
8576 case ARM::CDE_VCX3A_vec:
8577 case ARM::CDE_VCX3A_fpsp:
8578 case ARM::CDE_VCX3A_fpdp: {
8580 "CDE operand 1 must be a coprocessor ID");
8584 "coprocessor must be configured as CDE");
8585 else if (Coproc >= 8)
8587 "coprocessor must be in the range [p0, p7]");
8593 case ARM::t2LDC2L_OFFSET:
8594 case ARM::t2LDC2L_OPTION:
8595 case ARM::t2LDC2L_POST:
8596 case ARM::t2LDC2L_PRE:
8597 case ARM::t2LDC2_OFFSET:
8598 case ARM::t2LDC2_OPTION:
8599 case ARM::t2LDC2_POST:
8600 case ARM::t2LDC2_PRE:
8601 case ARM::t2LDCL_OFFSET:
8602 case ARM::t2LDCL_OPTION:
8603 case ARM::t2LDCL_POST:
8604 case ARM::t2LDCL_PRE:
8605 case ARM::t2LDC_OFFSET:
8606 case ARM::t2LDC_OPTION:
8607 case ARM::t2LDC_POST:
8608 case ARM::t2LDC_PRE:
8617 case ARM::t2STC2L_OFFSET:
8618 case ARM::t2STC2L_OPTION:
8619 case ARM::t2STC2L_POST:
8620 case ARM::t2STC2L_PRE:
8621 case ARM::t2STC2_OFFSET:
8622 case ARM::t2STC2_OPTION:
8623 case ARM::t2STC2_POST:
8624 case ARM::t2STC2_PRE:
8625 case ARM::t2STCL_OFFSET:
8626 case ARM::t2STCL_OPTION:
8627 case ARM::t2STCL_POST:
8628 case ARM::t2STCL_PRE:
8629 case ARM::t2STC_OFFSET:
8630 case ARM::t2STC_OPTION:
8631 case ARM::t2STC_POST:
8632 case ARM::t2STC_PRE: {
8637 if (Opcode == ARM::t2MRRC || Opcode == ARM::t2MRRC2)
8639 else if (Opcode == ARM::t2MRC || Opcode == ARM::t2MRC2)
8642 "Operand must be a coprocessor ID");
8647 "coprocessor must be configured as GCP");
8678 "source and destination registers must be the same");
8690 case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8691 case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8692 case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8693 case ARM::VST1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST1LNd8_UPD;
8694 case ARM::VST1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST1LNd16_UPD;
8695 case ARM::VST1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST1LNd32_UPD;
8696 case ARM::VST1LNdAsm_8: Spacing = 1;
return ARM::VST1LNd8;
8697 case ARM::VST1LNdAsm_16: Spacing = 1;
return ARM::VST1LNd16;
8698 case ARM::VST1LNdAsm_32: Spacing = 1;
return ARM::VST1LNd32;
8701 case ARM::VST2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8702 case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8703 case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8704 case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8705 case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8707 case ARM::VST2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST2LNd8_UPD;
8708 case ARM::VST2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST2LNd16_UPD;
8709 case ARM::VST2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST2LNd32_UPD;
8710 case ARM::VST2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST2LNq16_UPD;
8711 case ARM::VST2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST2LNq32_UPD;
8713 case ARM::VST2LNdAsm_8: Spacing = 1;
return ARM::VST2LNd8;
8714 case ARM::VST2LNdAsm_16: Spacing = 1;
return ARM::VST2LNd16;
8715 case ARM::VST2LNdAsm_32: Spacing = 1;
return ARM::VST2LNd32;
8716 case ARM::VST2LNqAsm_16: Spacing = 2;
return ARM::VST2LNq16;
8717 case ARM::VST2LNqAsm_32: Spacing = 2;
return ARM::VST2LNq32;
8720 case ARM::VST3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8721 case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8722 case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8723 case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3LNq16_UPD;
8724 case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8725 case ARM::VST3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST3LNd8_UPD;
8726 case ARM::VST3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST3LNd16_UPD;
8727 case ARM::VST3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST3LNd32_UPD;
8728 case ARM::VST3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST3LNq16_UPD;
8729 case ARM::VST3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST3LNq32_UPD;
8730 case ARM::VST3LNdAsm_8: Spacing = 1;
return ARM::VST3LNd8;
8731 case ARM::VST3LNdAsm_16: Spacing = 1;
return ARM::VST3LNd16;
8732 case ARM::VST3LNdAsm_32: Spacing = 1;
return ARM::VST3LNd32;
8733 case ARM::VST3LNqAsm_16: Spacing = 2;
return ARM::VST3LNq16;
8734 case ARM::VST3LNqAsm_32: Spacing = 2;
return ARM::VST3LNq32;
8737 case ARM::VST3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8738 case ARM::VST3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8739 case ARM::VST3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8740 case ARM::VST3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8741 case ARM::VST3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8742 case ARM::VST3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8743 case ARM::VST3dWB_register_Asm_8: Spacing = 1;
return ARM::VST3d8_UPD;
8744 case ARM::VST3dWB_register_Asm_16: Spacing = 1;
return ARM::VST3d16_UPD;
8745 case ARM::VST3dWB_register_Asm_32: Spacing = 1;
return ARM::VST3d32_UPD;
8746 case ARM::VST3qWB_register_Asm_8: Spacing = 2;
return ARM::VST3q8_UPD;
8747 case ARM::VST3qWB_register_Asm_16: Spacing = 2;
return ARM::VST3q16_UPD;
8748 case ARM::VST3qWB_register_Asm_32: Spacing = 2;
return ARM::VST3q32_UPD;
8749 case ARM::VST3dAsm_8: Spacing = 1;
return ARM::VST3d8;
8750 case ARM::VST3dAsm_16: Spacing = 1;
return ARM::VST3d16;
8751 case ARM::VST3dAsm_32: Spacing = 1;
return ARM::VST3d32;
8752 case ARM::VST3qAsm_8: Spacing = 2;
return ARM::VST3q8;
8753 case ARM::VST3qAsm_16: Spacing = 2;
return ARM::VST3q16;
8754 case ARM::VST3qAsm_32: Spacing = 2;
return ARM::VST3q32;
8757 case ARM::VST4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8758 case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8759 case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8760 case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4LNq16_UPD;
8761 case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8762 case ARM::VST4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VST4LNd8_UPD;
8763 case ARM::VST4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VST4LNd16_UPD;
8764 case ARM::VST4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VST4LNd32_UPD;
8765 case ARM::VST4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VST4LNq16_UPD;
8766 case ARM::VST4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VST4LNq32_UPD;
8767 case ARM::VST4LNdAsm_8: Spacing = 1;
return ARM::VST4LNd8;
8768 case ARM::VST4LNdAsm_16: Spacing = 1;
return ARM::VST4LNd16;
8769 case ARM::VST4LNdAsm_32: Spacing = 1;
return ARM::VST4LNd32;
8770 case ARM::VST4LNqAsm_16: Spacing = 2;
return ARM::VST4LNq16;
8771 case ARM::VST4LNqAsm_32: Spacing = 2;
return ARM::VST4LNq32;
8774 case ARM::VST4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8775 case ARM::VST4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8776 case ARM::VST4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8777 case ARM::VST4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8778 case ARM::VST4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8779 case ARM::VST4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8780 case ARM::VST4dWB_register_Asm_8: Spacing = 1;
return ARM::VST4d8_UPD;
8781 case ARM::VST4dWB_register_Asm_16: Spacing = 1;
return ARM::VST4d16_UPD;
8782 case ARM::VST4dWB_register_Asm_32: Spacing = 1;
return ARM::VST4d32_UPD;
8783 case ARM::VST4qWB_register_Asm_8: Spacing = 2;
return ARM::VST4q8_UPD;
8784 case ARM::VST4qWB_register_Asm_16: Spacing = 2;
return ARM::VST4q16_UPD;
8785 case ARM::VST4qWB_register_Asm_32: Spacing = 2;
return ARM::VST4q32_UPD;
8786 case ARM::VST4dAsm_8: Spacing = 1;
return ARM::VST4d8;
8787 case ARM::VST4dAsm_16: Spacing = 1;
return ARM::VST4d16;
8788 case ARM::VST4dAsm_32: Spacing = 1;
return ARM::VST4d32;
8789 case ARM::VST4qAsm_8: Spacing = 2;
return ARM::VST4q8;
8790 case ARM::VST4qAsm_16: Spacing = 2;
return ARM::VST4q16;
8791 case ARM::VST4qAsm_32: Spacing = 2;
return ARM::VST4q32;
8799 case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8800 case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8801 case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8802 case ARM::VLD1LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD1LNd8_UPD;
8803 case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD1LNd16_UPD;
8804 case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD1LNd32_UPD;
8805 case ARM::VLD1LNdAsm_8: Spacing = 1;
return ARM::VLD1LNd8;
8806 case ARM::VLD1LNdAsm_16: Spacing = 1;
return ARM::VLD1LNd16;
8807 case ARM::VLD1LNdAsm_32: Spacing = 1;
return ARM::VLD1LNd32;
8810 case ARM::VLD2LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8811 case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8812 case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8813 case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD2LNq16_UPD;
8814 case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8815 case ARM::VLD2LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD2LNd8_UPD;
8816 case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD2LNd16_UPD;
8817 case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD2LNd32_UPD;
8818 case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD2LNq16_UPD;
8819 case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD2LNq32_UPD;
8820 case ARM::VLD2LNdAsm_8: Spacing = 1;
return ARM::VLD2LNd8;
8821 case ARM::VLD2LNdAsm_16: Spacing = 1;
return ARM::VLD2LNd16;
8822 case ARM::VLD2LNdAsm_32: Spacing = 1;
return ARM::VLD2LNd32;
8823 case ARM::VLD2LNqAsm_16: Spacing = 2;
return ARM::VLD2LNq16;
8824 case ARM::VLD2LNqAsm_32: Spacing = 2;
return ARM::VLD2LNq32;
8827 case ARM::VLD3DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8828 case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8829 case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8830 case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3DUPq8_UPD;
8831 case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8832 case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8833 case ARM::VLD3DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3DUPd8_UPD;
8834 case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3DUPd16_UPD;
8835 case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3DUPd32_UPD;
8836 case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD3DUPq8_UPD;
8837 case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3DUPq16_UPD;
8838 case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3DUPq32_UPD;
8839 case ARM::VLD3DUPdAsm_8: Spacing = 1;
return ARM::VLD3DUPd8;
8840 case ARM::VLD3DUPdAsm_16: Spacing = 1;
return ARM::VLD3DUPd16;
8841 case ARM::VLD3DUPdAsm_32: Spacing = 1;
return ARM::VLD3DUPd32;
8842 case ARM::VLD3DUPqAsm_8: Spacing = 2;
return ARM::VLD3DUPq8;
8843 case ARM::VLD3DUPqAsm_16: Spacing = 2;
return ARM::VLD3DUPq16;
8844 case ARM::VLD3DUPqAsm_32: Spacing = 2;
return ARM::VLD3DUPq32;
8847 case ARM::VLD3LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8848 case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8849 case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8850 case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3LNq16_UPD;
8851 case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8852 case ARM::VLD3LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD3LNd8_UPD;
8853 case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD3LNd16_UPD;
8854 case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD3LNd32_UPD;
8855 case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD3LNq16_UPD;
8856 case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD3LNq32_UPD;
8857 case ARM::VLD3LNdAsm_8: Spacing = 1;
return ARM::VLD3LNd8;
8858 case ARM::VLD3LNdAsm_16: Spacing = 1;
return ARM::VLD3LNd16;
8859 case ARM::VLD3LNdAsm_32: Spacing = 1;
return ARM::VLD3LNd32;
8860 case ARM::VLD3LNqAsm_16: Spacing = 2;
return ARM::VLD3LNq16;
8861 case ARM::VLD3LNqAsm_32: Spacing = 2;
return ARM::VLD3LNq32;
8864 case ARM::VLD3dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8865 case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8866 case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8867 case ARM::VLD3qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8868 case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8869 case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8870 case ARM::VLD3dWB_register_Asm_8: Spacing = 1;
return ARM::VLD3d8_UPD;
8871 case ARM::VLD3dWB_register_Asm_16: Spacing = 1;
return ARM::VLD3d16_UPD;
8872 case ARM::VLD3dWB_register_Asm_32: Spacing = 1;
return ARM::VLD3d32_UPD;
8873 case ARM::VLD3qWB_register_Asm_8: Spacing = 2;
return ARM::VLD3q8_UPD;
8874 case ARM::VLD3qWB_register_Asm_16: Spacing = 2;
return ARM::VLD3q16_UPD;
8875 case ARM::VLD3qWB_register_Asm_32: Spacing = 2;
return ARM::VLD3q32_UPD;
8876 case ARM::VLD3dAsm_8: Spacing = 1;
return ARM::VLD3d8;
8877 case ARM::VLD3dAsm_16: Spacing = 1;
return ARM::VLD3d16;
8878 case ARM::VLD3dAsm_32: Spacing = 1;
return ARM::VLD3d32;
8879 case ARM::VLD3qAsm_8: Spacing = 2;
return ARM::VLD3q8;
8880 case ARM::VLD3qAsm_16: Spacing = 2;
return ARM::VLD3q16;
8881 case ARM::VLD3qAsm_32: Spacing = 2;
return ARM::VLD3q32;
8884 case ARM::VLD4LNdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8885 case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8886 case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8887 case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8888 case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8889 case ARM::VLD4LNdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4LNd8_UPD;
8890 case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4LNd16_UPD;
8891 case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4LNd32_UPD;
8892 case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4LNq16_UPD;
8893 case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4LNq32_UPD;
8894 case ARM::VLD4LNdAsm_8: Spacing = 1;
return ARM::VLD4LNd8;
8895 case ARM::VLD4LNdAsm_16: Spacing = 1;
return ARM::VLD4LNd16;
8896 case ARM::VLD4LNdAsm_32: Spacing = 1;
return ARM::VLD4LNd32;
8897 case ARM::VLD4LNqAsm_16: Spacing = 2;
return ARM::VLD4LNq16;
8898 case ARM::VLD4LNqAsm_32: Spacing = 2;
return ARM::VLD4LNq32;
8901 case ARM::VLD4DUPdWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8902 case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8903 case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8904 case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4DUPq8_UPD;
8905 case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4DUPq16_UPD;
8906 case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8907 case ARM::VLD4DUPdWB_register_Asm_8: Spacing = 1;
return ARM::VLD4DUPd8_UPD;
8908 case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1;
return ARM::VLD4DUPd16_UPD;
8909 case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1;
return ARM::VLD4DUPd32_UPD;
8910 case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2;
return ARM::VLD4DUPq8_UPD;
8911 case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2;
return ARM::VLD4DUPq16_UPD;
8912 case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2;
return ARM::VLD4DUPq32_UPD;
8913 case ARM::VLD4DUPdAsm_8: Spacing = 1;
return ARM::VLD4DUPd8;
8914 case ARM::VLD4DUPdAsm_16: Spacing = 1;
return ARM::VLD4DUPd16;
8915 case ARM::VLD4DUPdAsm_32: Spacing = 1;
return ARM::VLD4DUPd32;
8916 case ARM::VLD4DUPqAsm_8: Spacing = 2;
return ARM::VLD4DUPq8;
8917 case ARM::VLD4DUPqAsm_16: Spacing = 2;
return ARM::VLD4DUPq16;
8918 case ARM::VLD4DUPqAsm_32: Spacing = 2;
return ARM::VLD4DUPq32;
8921 case ARM::VLD4dWB_fixed_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8922 case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8923 case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8924 case ARM::VLD4qWB_fixed_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8925 case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8926 case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8927 case ARM::VLD4dWB_register_Asm_8: Spacing = 1;
return ARM::VLD4d8_UPD;
8928 case ARM::VLD4dWB_register_Asm_16: Spacing = 1;
return ARM::VLD4d16_UPD;
8929 case ARM::VLD4dWB_register_Asm_32: Spacing = 1;
return ARM::VLD4d32_UPD;
8930 case ARM::VLD4qWB_register_Asm_8: Spacing = 2;
return ARM::VLD4q8_UPD;
8931 case ARM::VLD4qWB_register_Asm_16: Spacing = 2;
return ARM::VLD4q16_UPD;
8932 case ARM::VLD4qWB_register_Asm_32: Spacing = 2;
return ARM::VLD4q32_UPD;
8933 case ARM::VLD4dAsm_8: Spacing = 1;
return ARM::VLD4d8;
8934 case ARM::VLD4dAsm_16: Spacing = 1;
return ARM::VLD4d16;
8935 case ARM::VLD4dAsm_32: Spacing = 1;
return ARM::VLD4d32;
8936 case ARM::VLD4qAsm_8: Spacing = 2;
return ARM::VLD4q8;
8937 case ARM::VLD4qAsm_16: Spacing = 2;
return ARM::VLD4q16;
8938 case ARM::VLD4qAsm_32: Spacing = 2;
return ARM::VLD4q32;
8942bool ARMAsmParser::processInstruction(MCInst &Inst,
8944 unsigned MnemonicOpsEndInd,
8948 bool HasWideQualifier =
false;
8950 ARMOperand &ARMOp =
static_cast<ARMOperand&
>(*Op);
8951 if (ARMOp.isToken() && ARMOp.getToken() ==
".w") {
8952 HasWideQualifier =
true;
8963 MnemonicOpsEndInd + 2) {
8964 ARMOperand &
Op =
static_cast<ARMOperand &
>(
8967 auto &RegList =
Op.getRegList();
8970 if (RegList.size() == 32) {
8971 const unsigned Opcode =
8972 (Inst.
getOpcode() == ARM::VLLDM) ? ARM::VLLDM_T2 : ARM::VLSTM_T2;
8986 case ARM::LDRT_POST:
8987 case ARM::LDRBT_POST: {
8988 const unsigned Opcode =
8989 (Inst.
getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
8990 : ARM::LDRBT_POST_IMM;
9006 case ARM::LDRSHTii: {
9011 else if (Inst.
getOpcode() == ARM::LDRHTii)
9013 else if (Inst.
getOpcode() == ARM::LDRSHTii)
9024 case ARM::STRT_POST:
9025 case ARM::STRBT_POST: {
9026 const unsigned Opcode =
9027 (Inst.
getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
9028 : ARM::STRBT_POST_IMM;
9077 case ARM::t2LDR_PRE_imm:
9078 case ARM::t2LDR_POST_imm: {
9092 case ARM::t2STR_PRE_imm:
9093 case ARM::t2STR_POST_imm: {
9107 case ARM::t2LDRB_OFFSET_imm: {
9117 case ARM::t2LDRB_PRE_imm:
9118 case ARM::t2LDRB_POST_imm: {
9122 : ARM::t2LDRB_POST);
9133 case ARM::t2STRB_OFFSET_imm: {
9143 case ARM::t2STRB_PRE_imm:
9144 case ARM::t2STRB_POST_imm: {
9148 : ARM::t2STRB_POST);
9159 case ARM::t2LDRH_OFFSET_imm: {
9169 case ARM::t2LDRH_PRE_imm:
9170 case ARM::t2LDRH_POST_imm: {
9174 : ARM::t2LDRH_POST);
9185 case ARM::t2STRH_OFFSET_imm: {
9195 case ARM::t2STRH_PRE_imm:
9196 case ARM::t2STRH_POST_imm: {
9200 : ARM::t2STRH_POST);
9211 case ARM::t2LDRSB_OFFSET_imm: {
9221 case ARM::t2LDRSB_PRE_imm:
9222 case ARM::t2LDRSB_POST_imm: {
9226 : ARM::t2LDRSB_POST);
9237 case ARM::t2LDRSH_OFFSET_imm: {
9247 case ARM::t2LDRSH_PRE_imm:
9248 case ARM::t2LDRSH_POST_imm: {
9252 : ARM::t2LDRSH_POST);
9263 case ARM::t2LDRpcrel:
9272 case ARM::t2LDRBpcrel:
9275 case ARM::t2LDRHpcrel:
9278 case ARM::t2LDRSBpcrel:
9281 case ARM::t2LDRSHpcrel:
9284 case ARM::LDRConstPool:
9285 case ARM::tLDRConstPool:
9286 case ARM::t2LDRConstPool: {
9291 if (Inst.
getOpcode() == ARM::LDRConstPool)
9293 else if (Inst.
getOpcode() == ARM::tLDRConstPool)
9295 else if (Inst.
getOpcode() == ARM::t2LDRConstPool)
9297 const ARMOperand &PoolOperand =
9298 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1]);
9299 const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
9307 bool MovHasS =
true;
9308 if (Inst.
getOpcode() == ARM::LDRConstPool) {
9318 else if (hasV6T2Ops() &&
9331 else if (hasThumb2() &&
9336 else if (hasV8MBaseline() &&
9356 const MCExpr *CPLoc =
9357 getTargetStreamer().addConstantPoolEntry(SubExprVal,
9358 PoolOperand.getStartLoc());
9369 case ARM::VST1LNdWB_register_Asm_8:
9370 case ARM::VST1LNdWB_register_Asm_16:
9371 case ARM::VST1LNdWB_register_Asm_32: {
9389 case ARM::VST2LNdWB_register_Asm_8:
9390 case ARM::VST2LNdWB_register_Asm_16:
9391 case ARM::VST2LNdWB_register_Asm_32:
9392 case ARM::VST2LNqWB_register_Asm_16:
9393 case ARM::VST2LNqWB_register_Asm_32: {
9413 case ARM::VST3LNdWB_register_Asm_8:
9414 case ARM::VST3LNdWB_register_Asm_16:
9415 case ARM::VST3LNdWB_register_Asm_32:
9416 case ARM::VST3LNqWB_register_Asm_16:
9417 case ARM::VST3LNqWB_register_Asm_32: {
9439 case ARM::VST4LNdWB_register_Asm_8:
9440 case ARM::VST4LNdWB_register_Asm_16:
9441 case ARM::VST4LNdWB_register_Asm_32:
9442 case ARM::VST4LNqWB_register_Asm_16:
9443 case ARM::VST4LNqWB_register_Asm_32: {
9467 case ARM::VST1LNdWB_fixed_Asm_8:
9468 case ARM::VST1LNdWB_fixed_Asm_16:
9469 case ARM::VST1LNdWB_fixed_Asm_32: {
9487 case ARM::VST2LNdWB_fixed_Asm_8:
9488 case ARM::VST2LNdWB_fixed_Asm_16:
9489 case ARM::VST2LNdWB_fixed_Asm_32:
9490 case ARM::VST2LNqWB_fixed_Asm_16:
9491 case ARM::VST2LNqWB_fixed_Asm_32: {
9511 case ARM::VST3LNdWB_fixed_Asm_8:
9512 case ARM::VST3LNdWB_fixed_Asm_16:
9513 case ARM::VST3LNdWB_fixed_Asm_32:
9514 case ARM::VST3LNqWB_fixed_Asm_16:
9515 case ARM::VST3LNqWB_fixed_Asm_32: {
9537 case ARM::VST4LNdWB_fixed_Asm_8:
9538 case ARM::VST4LNdWB_fixed_Asm_16:
9539 case ARM::VST4LNdWB_fixed_Asm_32:
9540 case ARM::VST4LNqWB_fixed_Asm_16:
9541 case ARM::VST4LNqWB_fixed_Asm_32: {
9565 case ARM::VST1LNdAsm_8:
9566 case ARM::VST1LNdAsm_16:
9567 case ARM::VST1LNdAsm_32: {
9583 case ARM::VST2LNdAsm_8:
9584 case ARM::VST2LNdAsm_16:
9585 case ARM::VST2LNdAsm_32:
9586 case ARM::VST2LNqAsm_16:
9587 case ARM::VST2LNqAsm_32: {
9605 case ARM::VST3LNdAsm_8:
9606 case ARM::VST3LNdAsm_16:
9607 case ARM::VST3LNdAsm_32:
9608 case ARM::VST3LNqAsm_16:
9609 case ARM::VST3LNqAsm_32: {
9629 case ARM::VST4LNdAsm_8:
9630 case ARM::VST4LNdAsm_16:
9631 case ARM::VST4LNdAsm_32:
9632 case ARM::VST4LNqAsm_16:
9633 case ARM::VST4LNqAsm_32: {
9656 case ARM::VLD1LNdWB_register_Asm_8:
9657 case ARM::VLD1LNdWB_register_Asm_16:
9658 case ARM::VLD1LNdWB_register_Asm_32: {
9677 case ARM::VLD2LNdWB_register_Asm_8:
9678 case ARM::VLD2LNdWB_register_Asm_16:
9679 case ARM::VLD2LNdWB_register_Asm_32:
9680 case ARM::VLD2LNqWB_register_Asm_16:
9681 case ARM::VLD2LNqWB_register_Asm_32: {
9704 case ARM::VLD3LNdWB_register_Asm_8:
9705 case ARM::VLD3LNdWB_register_Asm_16:
9706 case ARM::VLD3LNdWB_register_Asm_32:
9707 case ARM::VLD3LNqWB_register_Asm_16:
9708 case ARM::VLD3LNqWB_register_Asm_32: {
9735 case ARM::VLD4LNdWB_register_Asm_8:
9736 case ARM::VLD4LNdWB_register_Asm_16:
9737 case ARM::VLD4LNdWB_register_Asm_32:
9738 case ARM::VLD4LNqWB_register_Asm_16:
9739 case ARM::VLD4LNqWB_register_Asm_32: {
9770 case ARM::VLD1LNdWB_fixed_Asm_8:
9771 case ARM::VLD1LNdWB_fixed_Asm_16:
9772 case ARM::VLD1LNdWB_fixed_Asm_32: {
9791 case ARM::VLD2LNdWB_fixed_Asm_8:
9792 case ARM::VLD2LNdWB_fixed_Asm_16:
9793 case ARM::VLD2LNdWB_fixed_Asm_32:
9794 case ARM::VLD2LNqWB_fixed_Asm_16:
9795 case ARM::VLD2LNqWB_fixed_Asm_32: {
9818 case ARM::VLD3LNdWB_fixed_Asm_8:
9819 case ARM::VLD3LNdWB_fixed_Asm_16:
9820 case ARM::VLD3LNdWB_fixed_Asm_32:
9821 case ARM::VLD3LNqWB_fixed_Asm_16:
9822 case ARM::VLD3LNqWB_fixed_Asm_32: {
9849 case ARM::VLD4LNdWB_fixed_Asm_8:
9850 case ARM::VLD4LNdWB_fixed_Asm_16:
9851 case ARM::VLD4LNdWB_fixed_Asm_32:
9852 case ARM::VLD4LNqWB_fixed_Asm_16:
9853 case ARM::VLD4LNqWB_fixed_Asm_32: {
9884 case ARM::VLD1LNdAsm_8:
9885 case ARM::VLD1LNdAsm_16:
9886 case ARM::VLD1LNdAsm_32: {
9903 case ARM::VLD2LNdAsm_8:
9904 case ARM::VLD2LNdAsm_16:
9905 case ARM::VLD2LNdAsm_32:
9906 case ARM::VLD2LNqAsm_16:
9907 case ARM::VLD2LNqAsm_32: {
9928 case ARM::VLD3LNdAsm_8:
9929 case ARM::VLD3LNdAsm_16:
9930 case ARM::VLD3LNdAsm_32:
9931 case ARM::VLD3LNqAsm_16:
9932 case ARM::VLD3LNqAsm_32: {
9957 case ARM::VLD4LNdAsm_8:
9958 case ARM::VLD4LNdAsm_16:
9959 case ARM::VLD4LNdAsm_32:
9960 case ARM::VLD4LNqAsm_16:
9961 case ARM::VLD4LNqAsm_32: {
9991 case ARM::VLD3DUPdAsm_8:
9992 case ARM::VLD3DUPdAsm_16:
9993 case ARM::VLD3DUPdAsm_32:
9994 case ARM::VLD3DUPqAsm_8:
9995 case ARM::VLD3DUPqAsm_16:
9996 case ARM::VLD3DUPqAsm_32: {
10013 case ARM::VLD3DUPdWB_fixed_Asm_8:
10014 case ARM::VLD3DUPdWB_fixed_Asm_16:
10015 case ARM::VLD3DUPdWB_fixed_Asm_32:
10016 case ARM::VLD3DUPqWB_fixed_Asm_8:
10017 case ARM::VLD3DUPqWB_fixed_Asm_16:
10018 case ARM::VLD3DUPqWB_fixed_Asm_32: {
10037 case ARM::VLD3DUPdWB_register_Asm_8:
10038 case ARM::VLD3DUPdWB_register_Asm_16:
10039 case ARM::VLD3DUPdWB_register_Asm_32:
10040 case ARM::VLD3DUPqWB_register_Asm_8:
10041 case ARM::VLD3DUPqWB_register_Asm_16:
10042 case ARM::VLD3DUPqWB_register_Asm_32: {
10062 case ARM::VLD3dAsm_8:
10063 case ARM::VLD3dAsm_16:
10064 case ARM::VLD3dAsm_32:
10065 case ARM::VLD3qAsm_8:
10066 case ARM::VLD3qAsm_16:
10067 case ARM::VLD3qAsm_32: {
10084 case ARM::VLD3dWB_fixed_Asm_8:
10085 case ARM::VLD3dWB_fixed_Asm_16:
10086 case ARM::VLD3dWB_fixed_Asm_32:
10087 case ARM::VLD3qWB_fixed_Asm_8:
10088 case ARM::VLD3qWB_fixed_Asm_16:
10089 case ARM::VLD3qWB_fixed_Asm_32: {
10108 case ARM::VLD3dWB_register_Asm_8:
10109 case ARM::VLD3dWB_register_Asm_16:
10110 case ARM::VLD3dWB_register_Asm_32:
10111 case ARM::VLD3qWB_register_Asm_8:
10112 case ARM::VLD3qWB_register_Asm_16:
10113 case ARM::VLD3qWB_register_Asm_32: {
10133 case ARM::VLD4DUPdAsm_8:
10134 case ARM::VLD4DUPdAsm_16:
10135 case ARM::VLD4DUPdAsm_32:
10136 case ARM::VLD4DUPqAsm_8:
10137 case ARM::VLD4DUPqAsm_16:
10138 case ARM::VLD4DUPqAsm_32: {
10157 case ARM::VLD4DUPdWB_fixed_Asm_8:
10158 case ARM::VLD4DUPdWB_fixed_Asm_16:
10159 case ARM::VLD4DUPdWB_fixed_Asm_32:
10160 case ARM::VLD4DUPqWB_fixed_Asm_8:
10161 case ARM::VLD4DUPqWB_fixed_Asm_16:
10162 case ARM::VLD4DUPqWB_fixed_Asm_32: {
10183 case ARM::VLD4DUPdWB_register_Asm_8:
10184 case ARM::VLD4DUPdWB_register_Asm_16:
10185 case ARM::VLD4DUPdWB_register_Asm_32:
10186 case ARM::VLD4DUPqWB_register_Asm_8:
10187 case ARM::VLD4DUPqWB_register_Asm_16:
10188 case ARM::VLD4DUPqWB_register_Asm_32: {
10210 case ARM::VLD4dAsm_8:
10211 case ARM::VLD4dAsm_16:
10212 case ARM::VLD4dAsm_32:
10213 case ARM::VLD4qAsm_8:
10214 case ARM::VLD4qAsm_16:
10215 case ARM::VLD4qAsm_32: {
10234 case ARM::VLD4dWB_fixed_Asm_8:
10235 case ARM::VLD4dWB_fixed_Asm_16:
10236 case ARM::VLD4dWB_fixed_Asm_32:
10237 case ARM::VLD4qWB_fixed_Asm_8:
10238 case ARM::VLD4qWB_fixed_Asm_16:
10239 case ARM::VLD4qWB_fixed_Asm_32: {
10260 case ARM::VLD4dWB_register_Asm_8:
10261 case ARM::VLD4dWB_register_Asm_16:
10262 case ARM::VLD4dWB_register_Asm_32:
10263 case ARM::VLD4qWB_register_Asm_8:
10264 case ARM::VLD4qWB_register_Asm_16:
10265 case ARM::VLD4qWB_register_Asm_32: {
10287 case ARM::VST3dAsm_8:
10288 case ARM::VST3dAsm_16:
10289 case ARM::VST3dAsm_32:
10290 case ARM::VST3qAsm_8:
10291 case ARM::VST3qAsm_16:
10292 case ARM::VST3qAsm_32: {
10309 case ARM::VST3dWB_fixed_Asm_8:
10310 case ARM::VST3dWB_fixed_Asm_16:
10311 case ARM::VST3dWB_fixed_Asm_32:
10312 case ARM::VST3qWB_fixed_Asm_8:
10313 case ARM::VST3qWB_fixed_Asm_16:
10314 case ARM::VST3qWB_fixed_Asm_32: {
10333 case ARM::VST3dWB_register_Asm_8:
10334 case ARM::VST3dWB_register_Asm_16:
10335 case ARM::VST3dWB_register_Asm_32:
10336 case ARM::VST3qWB_register_Asm_8:
10337 case ARM::VST3qWB_register_Asm_16:
10338 case ARM::VST3qWB_register_Asm_32: {
10358 case ARM::VST4dAsm_8:
10359 case ARM::VST4dAsm_16:
10360 case ARM::VST4dAsm_32:
10361 case ARM::VST4qAsm_8:
10362 case ARM::VST4qAsm_16:
10363 case ARM::VST4qAsm_32: {
10382 case ARM::VST4dWB_fixed_Asm_8:
10383 case ARM::VST4dWB_fixed_Asm_16:
10384 case ARM::VST4dWB_fixed_Asm_32:
10385 case ARM::VST4qWB_fixed_Asm_8:
10386 case ARM::VST4qWB_fixed_Asm_16:
10387 case ARM::VST4qWB_fixed_Asm_32: {
10408 case ARM::VST4dWB_register_Asm_8:
10409 case ARM::VST4dWB_register_Asm_16:
10410 case ARM::VST4dWB_register_Asm_32:
10411 case ARM::VST4qWB_register_Asm_8:
10412 case ARM::VST4qWB_register_Asm_16:
10413 case ARM::VST4qWB_register_Asm_32: {
10441 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10442 !HasWideQualifier) {
10446 case ARM::t2LSLri: NewOpc = ARM::tLSLri;
break;
10447 case ARM::t2LSRri: NewOpc = ARM::tLSRri;
break;
10448 case ARM::t2ASRri: NewOpc = ARM::tASRri;
break;
10466 case ARM::t2MOVSsr: {
10470 bool isNarrow =
false;
10475 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsr) &&
10482 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr;
break;
10483 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr;
break;
10484 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr;
break;
10485 case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr;
break;
10491 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10498 Inst.
getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : ARM::NoRegister));
10503 case ARM::t2MOVSsi: {
10507 bool isNarrow =
false;
10510 inITBlock() == (Inst.
getOpcode() == ARM::t2MOVsi) &&
10517 bool isMov =
false;
10528 newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
10532 case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri;
break;
10533 case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri;
break;
10534 case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri;
break;
10535 case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow =
false;
break;
10536 case ARM_AM::rrx: isNarrow =
false; newOpc = ARM::t2RRX;
break;
10539 if (Amount == 32) Amount = 0;
10542 if (isNarrow && !isMov)
10544 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10546 if (newOpc != ARM::t2RRX && !isMov)
10552 Inst.
getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : ARM::NoRegister));
10596 unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
10605 if (
Opc == ARM::MOVsi)
10626 case ARM::t2LDMIA_UPD: {
10642 case ARM::t2STMDB_UPD: {
10658 case ARM::LDMIA_UPD:
10676 case ARM::STMDB_UPD:
10692 case ARM::t2ADDri12:
10693 case ARM::t2SUBri12:
10694 case ARM::t2ADDspImm12:
10695 case ARM::t2SUBspImm12: {
10698 const StringRef Token =
static_cast<ARMOperand &
>(*
Operands[0]).
getToken();
10699 if ((Token !=
"add" && Token !=
"sub") ||
10703 case ARM::t2ADDri12:
10706 case ARM::t2SUBri12:
10709 case ARM::t2ADDspImm12:
10712 case ARM::t2SUBspImm12:
10727 Operands.size() == MnemonicOpsEndInd + 3) {
10738 Operands.size() == MnemonicOpsEndInd + 3) {
10744 case ARM::t2SUBri: {
10749 if (HasWideQualifier)
10756 (inITBlock() ? ARM::NoRegister : ARM::CPSR))
10762 int i = (
Operands[MnemonicOpsEndInd + 1]->isImm())
10763 ? MnemonicOpsEndInd + 1
10764 : MnemonicOpsEndInd + 2;
10771 ARM::tADDi8 : ARM::tSUBi8);
10781 case ARM::t2ADDspImm:
10782 case ARM::t2SUBspImm: {
10787 if (V & 3 || V > ((1 << 7) - 1) << 2)
10800 case ARM::t2ADDrr: {
10862 case ARM::tLDMIA: {
10868 bool hasWritebackToken =
10869 (
static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
10871 static_cast<ARMOperand &
>(*
Operands[MnemonicOpsEndInd + 1])
10873 bool listContainsBase;
10875 (!listContainsBase && !hasWritebackToken) ||
10876 (listContainsBase && hasWritebackToken)) {
10879 Inst.
setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
10882 if (hasWritebackToken)
10889 case ARM::tSTMIA_UPD: {
10894 bool listContainsBase;
10904 bool listContainsBase;
10918 bool listContainsBase;
10935 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
10936 !HasWideQualifier) {
10957 !HasWideQualifier) {
10964 if (
Op == ARM::tMOVr) {
10982 !HasWideQualifier) {
10986 case ARM::t2SXTH: NewOpc = ARM::tSXTH;
break;
10987 case ARM::t2SXTB: NewOpc = ARM::tSXTB;
break;
10988 case ARM::t2UXTH: NewOpc = ARM::tUXTH;
break;
10989 case ARM::t2UXTB: NewOpc = ARM::tUXTB;
break;
11027 case ARM::ADDrsi: {
11033 case ARM::ANDrsi: newOpc = ARM::ANDrr;
break;
11034 case ARM::ORRrsi: newOpc = ARM::ORRrr;
break;
11035 case ARM::EORrsi: newOpc = ARM::EORrr;
break;
11036 case ARM::BICrsi: newOpc = ARM::BICrr;
break;
11037 case ARM::SUBrsi: newOpc = ARM::SUBrr;
break;
11038 case ARM::ADDrsi: newOpc = ARM::ADDrr;
break;
11061 assert(!inITBlock() &&
"nested IT blocks?!");
11077 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11078 !HasWideQualifier) {
11082 case ARM::t2LSLrr: NewOpc = ARM::tLSLrr;
break;
11083 case ARM::t2LSRrr: NewOpc = ARM::tLSRrr;
break;
11084 case ARM::t2ASRrr: NewOpc = ARM::tASRrr;
break;
11085 case ARM::t2SBCrr: NewOpc = ARM::tSBC;
break;
11086 case ARM::t2RORrr: NewOpc = ARM::tROR;
break;
11087 case ARM::t2BICrr: NewOpc = ARM::tBIC;
break;
11114 (inITBlock() ? ARM::NoRegister : ARM::CPSR) &&
11115 !HasWideQualifier) {
11119 case ARM::t2ADCrr: NewOpc = ARM::tADC;
break;
11120 case ARM::t2ANDrr: NewOpc = ARM::tAND;
break;
11121 case ARM::t2EORrr: NewOpc = ARM::tEOR;
break;
11122 case ARM::t2ORRrr: NewOpc = ARM::tORR;
break;
11141 case ARM::MVE_VPST:
11142 case ARM::MVE_VPTv16i8:
11143 case ARM::MVE_VPTv8i16:
11144 case ARM::MVE_VPTv4i32:
11145 case ARM::MVE_VPTv16u8:
11146 case ARM::MVE_VPTv8u16:
11147 case ARM::MVE_VPTv4u32:
11148 case ARM::MVE_VPTv16s8:
11149 case ARM::MVE_VPTv8s16:
11150 case ARM::MVE_VPTv4s32:
11151 case ARM::MVE_VPTv4f32:
11152 case ARM::MVE_VPTv8f16:
11153 case ARM::MVE_VPTv16i8r:
11154 case ARM::MVE_VPTv8i16r:
11155 case ARM::MVE_VPTv4i32r:
11156 case ARM::MVE_VPTv16u8r:
11157 case ARM::MVE_VPTv8u16r:
11158 case ARM::MVE_VPTv4u32r:
11159 case ARM::MVE_VPTv16s8r:
11160 case ARM::MVE_VPTv8s16r:
11161 case ARM::MVE_VPTv4s32r:
11162 case ARM::MVE_VPTv4f32r:
11163 case ARM::MVE_VPTv8f16r: {
11164 assert(!inVPTBlock() &&
"Nested VPT blocks are not allowed");
11166 VPTState.Mask = MO.
getImm();
11167 VPTState.CurPosition = 0;
11175ARMAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
11184 ((
isThumb() && !isThumbOne()) || hasV6MOps())) {
11185 return Match_MnemonicFail;
11190 return Match_Success;
11194unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11198 const MCInstrDesc &MCID = MII.get(
Opc);
11201 "optionally flag setting instruction missing optional def operand");
11203 "operand count mismatch!");
11204 bool IsCPSR =
false;
11206 for (
unsigned OpNo = 0; OpNo < MCID.
NumOperands; ++OpNo) {
11207 if (MCID.
operands()[OpNo].isOptionalDef() &&
11214 if (isThumbOne() && !IsCPSR)
11215 return Match_RequiresFlagSetting;
11218 if (isThumbTwo() && !IsCPSR && !inITBlock())
11219 return Match_RequiresITBlock;
11220 if (isThumbTwo() && IsCPSR && inITBlock())
11221 return Match_RequiresNotITBlock;
11224 return Match_RequiresNotITBlock;
11225 }
else if (isThumbOne()) {
11228 if (
Opc == ARM::tADDhirr && !hasV6MOps() &&
11231 return Match_RequiresThumb2;
11233 else if (
Opc == ARM::tMOVr && !hasV6Ops() &&
11236 return Match_RequiresV6;
11242 if (
Opc == ARM::t2MOVr && !hasV8Ops())
11247 return Match_RequiresV8;
11252 return Match_RequiresV8;
11258 case ARM::VMRS_FPCXTS:
11259 case ARM::VMRS_FPCXTNS:
11260 case ARM::VMSR_FPCXTS:
11261 case ARM::VMSR_FPCXTNS:
11262 case ARM::VMRS_FPSCR_NZCVQC:
11263 case ARM::VMSR_FPSCR_NZCVQC:
11265 case ARM::VMRS_VPR:
11267 case ARM::VMSR_VPR:
11273 return Match_InvalidOperand;
11279 return Match_RequiresV8;
11287 return Match_InvalidTiedOperand;
11294 if (MCID.
operands()[
I].RegClass == ARM::rGPRRegClassID) {
11309 MCRegister
Reg =
Op.getReg();
11310 if ((
Reg == ARM::SP) && !hasV8Ops())
11311 return Match_RequiresV8;
11312 else if (
Reg == ARM::PC)
11313 return Match_InvalidOperand;
11316 return Match_Success;
11329bool ARMAsmParser::isITBlockTerminator(MCInst &Inst)
const {
11330 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11347 SmallVectorImpl<NearMissInfo> &NearMisses,
11348 bool MatchingInlineAsm,
11349 bool &EmitInITBlock,
11352 if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
11353 return MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
11357 if (inImplicitITBlock()) {
11358 extendImplicitITBlock(ITState.Cond);
11359 if (MatchInstructionImpl(
Operands, Inst,
nullptr, MatchingInlineAsm) ==
11363 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11369 if (InstCond == ITCond) {
11370 EmitInITBlock =
true;
11371 return Match_Success;
11373 invertCurrentITCondition();
11374 EmitInITBlock =
true;
11375 return Match_Success;
11379 rewindImplicitITPosition();
11383 flushPendingInstructions(Out);
11384 unsigned PlainMatchResult =
11385 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
11386 if (PlainMatchResult == Match_Success) {
11387 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11395 EmitInITBlock =
false;
11396 return Match_Success;
11399 EmitInITBlock =
false;
11400 return Match_Success;
11403 EmitInITBlock =
false;
11404 return Match_Success;
11411 startImplicitITBlock();
11412 if (MatchInstructionImpl(
Operands, Inst,
nullptr, MatchingInlineAsm) ==
11414 const MCInstrDesc &MCID = MII.get(Inst.
getOpcode());
11419 EmitInITBlock =
true;
11420 return Match_Success;
11423 discardImplicitITBlock();
11427 EmitInITBlock =
false;
11428 return PlainMatchResult;
11432 unsigned VariantID = 0);
11435bool ARMAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
11438 bool MatchingInlineAsm) {
11440 unsigned MatchResult;
11441 bool PendConditionalInstruction =
false;
11444 MatchResult = MatchInstruction(
Operands, Inst, NearMisses, MatchingInlineAsm,
11445 PendConditionalInstruction, Out);
11450 switch (MatchResult) {
11451 case Match_Success:
11458 if (validateInstruction(Inst,
Operands, MnemonicOpsEndInd)) {
11461 forwardITPosition();
11462 forwardVPTPosition();
11471 while (processInstruction(Inst,
Operands, MnemonicOpsEndInd, Out))
11480 forwardITPosition();
11481 forwardVPTPosition();
11489 if (PendConditionalInstruction) {
11490 PendingConditionalInsts.
push_back(Inst);
11491 if (isITBlockFull() || isITBlockTerminator(Inst))
11492 flushPendingInstructions(Out);
11497 case Match_NearMisses:
11498 ReportNearMisses(NearMisses, IDLoc,
Operands);
11500 case Match_MnemonicFail: {
11501 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
11504 return Error(IDLoc,
"invalid instruction" + Suggestion,
11505 ((ARMOperand &)*
Operands[0]).getLocRange());
11513bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
11519 if (IDVal ==
".word")
11520 parseLiteralValues(4, DirectiveID.
getLoc());
11521 else if (IDVal ==
".short" || IDVal ==
".hword")
11522 parseLiteralValues(2, DirectiveID.
getLoc());
11523 else if (IDVal ==
".thumb")
11524 parseDirectiveThumb(DirectiveID.
getLoc());
11525 else if (IDVal ==
".arm")
11526 parseDirectiveARM(DirectiveID.
getLoc());
11527 else if (IDVal ==
".thumb_func")
11528 parseDirectiveThumbFunc(DirectiveID.
getLoc());
11529 else if (IDVal ==
".code")
11530 parseDirectiveCode(DirectiveID.
getLoc());
11531 else if (IDVal ==
".syntax")
11532 parseDirectiveSyntax(DirectiveID.
getLoc());
11533 else if (IDVal ==
".unreq")
11534 parseDirectiveUnreq(DirectiveID.
getLoc());
11535 else if (IDVal ==
".fnend")
11536 parseDirectiveFnEnd(DirectiveID.
getLoc());
11537 else if (IDVal ==
".cantunwind")
11538 parseDirectiveCantUnwind(DirectiveID.
getLoc());
11539 else if (IDVal ==
".personality")
11540 parseDirectivePersonality(DirectiveID.
getLoc());
11541 else if (IDVal ==
".handlerdata")
11542 parseDirectiveHandlerData(DirectiveID.
getLoc());
11543 else if (IDVal ==
".setfp")
11544 parseDirectiveSetFP(DirectiveID.
getLoc());
11545 else if (IDVal ==
".pad")
11546 parseDirectivePad(DirectiveID.
getLoc());
11547 else if (IDVal ==
".save")
11548 parseDirectiveRegSave(DirectiveID.
getLoc(),
false);
11549 else if (IDVal ==
".vsave")
11550 parseDirectiveRegSave(DirectiveID.
getLoc(),
true);
11551 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
11552 parseDirectiveLtorg(DirectiveID.
getLoc());
11553 else if (IDVal ==
".even")
11554 parseDirectiveEven(DirectiveID.
getLoc());
11555 else if (IDVal ==
".personalityindex")
11556 parseDirectivePersonalityIndex(DirectiveID.
getLoc());
11557 else if (IDVal ==
".unwind_raw")
11558 parseDirectiveUnwindRaw(DirectiveID.
getLoc());
11559 else if (IDVal ==
".movsp")
11560 parseDirectiveMovSP(DirectiveID.
getLoc());
11561 else if (IDVal ==
".arch_extension")
11562 parseDirectiveArchExtension(DirectiveID.
getLoc());
11563 else if (IDVal ==
".align")
11564 return parseDirectiveAlign(DirectiveID.
getLoc());
11565 else if (IDVal ==
".thumb_set")
11566 parseDirectiveThumbSet(DirectiveID.
getLoc());
11567 else if (IDVal ==
".inst")
11568 parseDirectiveInst(DirectiveID.
getLoc());
11569 else if (IDVal ==
".inst.n")
11570 parseDirectiveInst(DirectiveID.
getLoc(),
'n');
11571 else if (IDVal ==
".inst.w")
11572 parseDirectiveInst(DirectiveID.
getLoc(),
'w');
11573 else if (!IsMachO && !IsCOFF) {
11574 if (IDVal ==
".arch")
11575 parseDirectiveArch(DirectiveID.
getLoc());
11576 else if (IDVal ==
".cpu")
11577 parseDirectiveCPU(DirectiveID.
getLoc());
11578 else if (IDVal ==
".eabi_attribute")
11579 parseDirectiveEabiAttr(DirectiveID.
getLoc());
11580 else if (IDVal ==
".fpu")
11581 parseDirectiveFPU(DirectiveID.
getLoc());
11582 else if (IDVal ==
".fnstart")
11583 parseDirectiveFnStart(DirectiveID.
getLoc());
11584 else if (IDVal ==
".object_arch")
11585 parseDirectiveObjectArch(DirectiveID.
getLoc());
11586 else if (IDVal ==
".tlsdescseq")
11587 parseDirectiveTLSDescSeq(DirectiveID.
getLoc());
11590 }
else if (IsCOFF) {
11591 if (IDVal ==
".seh_stackalloc")
11592 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
false);
11593 else if (IDVal ==
".seh_stackalloc_w")
11594 parseDirectiveSEHAllocStack(DirectiveID.
getLoc(),
true);
11595 else if (IDVal ==
".seh_save_regs")
11596 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
false);
11597 else if (IDVal ==
".seh_save_regs_w")
11598 parseDirectiveSEHSaveRegs(DirectiveID.
getLoc(),
true);
11599 else if (IDVal ==
".seh_save_sp")
11600 parseDirectiveSEHSaveSP(DirectiveID.
getLoc());
11601 else if (IDVal ==
".seh_save_fregs")
11602 parseDirectiveSEHSaveFRegs(DirectiveID.
getLoc());
11603 else if (IDVal ==
".seh_save_lr")
11604 parseDirectiveSEHSaveLR(DirectiveID.
getLoc());
11605 else if (IDVal ==
".seh_endprologue")
11606 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
false);
11607 else if (IDVal ==
".seh_endprologue_fragment")
11608 parseDirectiveSEHPrologEnd(DirectiveID.
getLoc(),
true);
11609 else if (IDVal ==
".seh_nop")
11610 parseDirectiveSEHNop(DirectiveID.
getLoc(),
false);
11611 else if (IDVal ==
".seh_nop_w")
11612 parseDirectiveSEHNop(DirectiveID.
getLoc(),
true);
11613 else if (IDVal ==
".seh_startepilogue")
11614 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
false);
11615 else if (IDVal ==
".seh_startepilogue_cond")
11616 parseDirectiveSEHEpilogStart(DirectiveID.
getLoc(),
true);
11617 else if (IDVal ==
".seh_endepilogue")
11618 parseDirectiveSEHEpilogEnd(DirectiveID.
getLoc());
11619 else if (IDVal ==
".seh_custom")
11620 parseDirectiveSEHCustom(DirectiveID.
getLoc());
11632bool ARMAsmParser::parseLiteralValues(
unsigned Size, SMLoc L) {
11633 auto parseOne = [&]() ->
bool {
11634 const MCExpr *
Value;
11635 if (getParser().parseExpression(
Value))
11637 getParser().getStreamer().emitValue(
Value,
Size, L);
11640 return (parseMany(parseOne));
11645bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
11646 if (parseEOL() || check(!hasThumb(), L,
"target does not support Thumb mode"))
11652 getTargetStreamer().emitCode16();
11653 getParser().getStreamer().emitCodeAlignment(
Align(2), getSTI(), 0);
11659bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
11660 if (parseEOL() || check(!hasARM(), L,
"target does not support ARM mode"))
11665 getTargetStreamer().emitCode32();
11666 getParser().getStreamer().emitCodeAlignment(
Align(4), getSTI(), 0);
11670void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
11673 flushPendingInstructions(getStreamer());
11676void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
11677 if (NextSymbolIsThumb) {
11678 getTargetStreamer().emitThumbFunc(Symbol);
11679 NextSymbolIsThumb =
false;
11685bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
11686 MCAsmParser &Parser = getParser();
11696 MCSymbol *
Func = getParser().getContext().getOrCreateSymbol(
11698 getTargetStreamer().emitThumbFunc(Func);
11713 getTargetStreamer().emitCode16();
11715 NextSymbolIsThumb =
true;
11721bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
11722 MCAsmParser &Parser = getParser();
11723 const AsmToken &Tok = Parser.
getTok();
11725 Error(L,
"unexpected token in .syntax directive");
11731 if (check(
Mode ==
"divided" ||
Mode ==
"DIVIDED", L,
11732 "'.syntax divided' arm assembly not supported") ||
11733 check(
Mode !=
"unified" &&
Mode !=
"UNIFIED", L,
11734 "unrecognized syntax mode in .syntax directive") ||
11745bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
11746 MCAsmParser &Parser = getParser();
11747 const AsmToken &Tok = Parser.
getTok();
11749 return Error(L,
"unexpected token in .code directive");
11751 if (Val != 16 && Val != 32) {
11752 Error(L,
"invalid operand to .code directive");
11762 return Error(L,
"target does not support Thumb mode");
11766 getTargetStreamer().emitCode16();
11769 return Error(L,
"target does not support ARM mode");
11773 getTargetStreamer().emitCode32();
11781bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
11782 MCAsmParser &Parser = getParser();
11785 SMLoc SRegLoc, ERegLoc;
11786 const bool parseResult = parseRegister(
Reg, SRegLoc, ERegLoc);
11787 if (check(parseResult, SRegLoc,
"register name expected") || parseEOL())
11790 if (RegisterReqs.
insert(std::make_pair(Name,
Reg)).first->second !=
Reg)
11791 return Error(SRegLoc,
11792 "redefinition of '" + Name +
"' does not match original.");
11799bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
11800 MCAsmParser &Parser = getParser();
11802 return Error(L,
"unexpected input in .unreq directive.");
11811void ARMAsmParser::FixModeAfterArchChange(
bool WasThumb, SMLoc Loc) {
11813 if (WasThumb && hasThumb()) {
11816 }
else if (!WasThumb && hasARM()) {
11822 getTargetStreamer().emitCode16();
11824 getTargetStreamer().emitCode32();
11828 Warning(Loc, Twine(
"new target does not support ") +
11829 (WasThumb ?
"thumb" :
"arm") +
" mode, switching to " +
11830 (!WasThumb ?
"thumb" :
"arm") +
" mode");
11837bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
11838 StringRef Arch = getParser().parseStringToEndOfStatement().trim();
11841 if (ID == ARM::ArchKind::INVALID)
11842 return Error(L,
"Unknown arch name");
11845 MCSubtargetInfo &STI = copySTI();
11848 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11849 FixModeAfterArchChange(WasThumb, L);
11851 getTargetStreamer().emitArch(ID);
11858bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
11859 MCAsmParser &Parser = getParser();
11868 Error(TagLoc,
"attribute name not recognised: " + Name);
11874 const MCExpr *AttrExpr;
11881 if (check(!CE, TagLoc,
"expected numeric constant"))
11884 Tag =
CE->getValue();
11890 StringRef StringValue =
"";
11891 bool IsStringValue =
false;
11893 int64_t IntegerValue = 0;
11894 bool IsIntegerValue =
false;
11897 IsStringValue =
true;
11899 IsStringValue =
true;
11900 IsIntegerValue =
true;
11901 }
else if (
Tag < 32 ||
Tag % 2 == 0)
11902 IsIntegerValue =
true;
11903 else if (
Tag % 2 == 1)
11904 IsStringValue =
true;
11908 if (IsIntegerValue) {
11909 const MCExpr *ValueExpr;
11916 return Error(ValueExprLoc,
"expected numeric constant");
11917 IntegerValue =
CE->getValue();
11925 std::string EscapedValue;
11926 if (IsStringValue) {
11934 StringValue = EscapedValue;
11944 if (IsIntegerValue && IsStringValue) {
11946 getTargetStreamer().emitIntTextAttribute(
Tag, IntegerValue, StringValue);
11947 }
else if (IsIntegerValue)
11948 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
11949 else if (IsStringValue)
11950 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
11956bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
11957 StringRef CPU = getParser().parseStringToEndOfStatement().trim();
11962 if (!getSTI().isCPUStringValid(CPU))
11963 return Error(L,
"Unknown CPU name");
11966 MCSubtargetInfo &STI = copySTI();
11968 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11969 FixModeAfterArchChange(WasThumb, L);
11976bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
11977 SMLoc FPUNameLoc = getTok().getLoc();
11978 StringRef FPU = getParser().parseStringToEndOfStatement().trim();
11981 std::vector<StringRef> Features;
11983 return Error(FPUNameLoc,
"Unknown FPU name");
11985 MCSubtargetInfo &STI = copySTI();
11986 for (
auto Feature : Features)
11988 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
11990 getTargetStreamer().emitFPU(ID);
11996bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
12000 if (UC.hasFnStart()) {
12001 Error(L,
".fnstart starts before the end of previous one");
12002 UC.emitFnStartLocNotes();
12009 getTargetStreamer().emitFnStart();
12011 UC.recordFnStart(L);
12017bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
12021 if (!UC.hasFnStart())
12022 return Error(L,
".fnstart must precede .fnend directive");
12025 getTargetStreamer().emitFnEnd();
12033bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
12037 UC.recordCantUnwind(L);
12039 if (check(!UC.hasFnStart(), L,
".fnstart must precede .cantunwind directive"))
12042 if (UC.hasHandlerData()) {
12043 Error(L,
".cantunwind can't be used with .handlerdata directive");
12044 UC.emitHandlerDataLocNotes();
12047 if (UC.hasPersonality()) {
12048 Error(L,
".cantunwind can't be used with .personality directive");
12049 UC.emitPersonalityLocNotes();
12053 getTargetStreamer().emitCantUnwind();
12059bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
12060 MCAsmParser &Parser = getParser();
12061 bool HasExistingPersonality = UC.hasPersonality();
12065 return Error(L,
"unexpected input in .personality directive.");
12072 UC.recordPersonality(L);
12075 if (!UC.hasFnStart())
12076 return Error(L,
".fnstart must precede .personality directive");
12077 if (UC.cantUnwind()) {
12078 Error(L,
".personality can't be used with .cantunwind directive");
12079 UC.emitCantUnwindLocNotes();
12082 if (UC.hasHandlerData()) {
12083 Error(L,
".personality must precede .handlerdata directive");
12084 UC.emitHandlerDataLocNotes();
12087 if (HasExistingPersonality) {
12088 Error(L,
"multiple personality directives");
12089 UC.emitPersonalityLocNotes();
12093 MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
12094 getTargetStreamer().emitPersonality(PR);
12100bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
12104 UC.recordHandlerData(L);
12106 if (!UC.hasFnStart())
12107 return Error(L,
".fnstart must precede .personality directive");
12108 if (UC.cantUnwind()) {
12109 Error(L,
".handlerdata can't be used with .cantunwind directive");
12110 UC.emitCantUnwindLocNotes();
12114 getTargetStreamer().emitHandlerData();
12120bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
12121 MCAsmParser &Parser = getParser();
12123 if (check(!UC.hasFnStart(), L,
".fnstart must precede .setfp directive") ||
12124 check(UC.hasHandlerData(), L,
12125 ".setfp must precede .handlerdata directive"))
12130 MCRegister
FPReg = tryParseRegister();
12132 if (check(!
FPReg, FPRegLoc,
"frame pointer register expected") ||
12138 MCRegister
SPReg = tryParseRegister();
12139 if (check(!
SPReg, SPRegLoc,
"stack pointer register expected") ||
12140 check(
SPReg != ARM::SP &&
SPReg != UC.getFPReg(), SPRegLoc,
12141 "register should be either $sp or the latest fp register"))
12145 UC.saveFPReg(
FPReg);
12155 const MCExpr *OffsetExpr;
12158 if (getParser().parseExpression(OffsetExpr, EndLoc))
12159 return Error(ExLoc,
"malformed setfp offset");
12161 if (check(!CE, ExLoc,
"setfp offset must be an immediate"))
12175bool ARMAsmParser::parseDirectivePad(SMLoc L) {
12176 MCAsmParser &Parser = getParser();
12178 if (!UC.hasFnStart())
12179 return Error(L,
".fnstart must precede .pad directive");
12180 if (UC.hasHandlerData())
12181 return Error(L,
".pad must precede .handlerdata directive");
12189 const MCExpr *OffsetExpr;
12192 if (getParser().parseExpression(OffsetExpr, EndLoc))
12193 return Error(ExLoc,
"malformed pad offset");
12196 return Error(ExLoc,
"pad offset must be an immediate");
12201 getTargetStreamer().emitPad(
CE->getValue());
12208bool ARMAsmParser::parseDirectiveRegSave(SMLoc L,
bool IsVector) {
12210 if (!UC.hasFnStart())
12211 return Error(L,
".fnstart must precede .save or .vsave directives");
12212 if (UC.hasHandlerData())
12213 return Error(L,
".save or .vsave must precede .handlerdata directive");
12219 if (parseRegisterList(
Operands,
true,
true) || parseEOL())
12221 ARMOperand &
Op = (ARMOperand &)*
Operands[0];
12222 if (!IsVector && !
Op.isRegList())
12223 return Error(L,
".save expects GPR registers");
12224 if (IsVector && !
Op.isDPRRegList())
12225 return Error(L,
".vsave expects DPR registers");
12227 getTargetStreamer().emitRegSave(
Op.getRegList(), IsVector);
12235bool ARMAsmParser::parseDirectiveInst(SMLoc Loc,
char Suffix) {
12251 return Error(Loc,
"width suffixes are invalid in ARM mode");
12254 auto parseOne = [&]() ->
bool {
12255 const MCExpr *Expr;
12256 if (getParser().parseExpression(Expr))
12260 return Error(Loc,
"expected constant expression");
12263 char CurSuffix = Suffix;
12266 if (
Value->getValue() > 0xffff)
12267 return Error(Loc,
"inst.n operand is too big, use inst.w instead");
12270 if (
Value->getValue() > 0xffffffff)
12271 return Error(Loc, StringRef(Suffix ?
"inst.w" :
"inst") +
12272 " operand is too big");
12276 if (
Value->getValue() < 0xe800)
12278 else if (
Value->getValue() >= 0xe8000000)
12281 return Error(Loc,
"cannot determine Thumb instruction size, "
12282 "use inst.n/inst.w instead");
12288 getTargetStreamer().emitInst(
Value->getValue(), CurSuffix);
12289 forwardITPosition();
12290 forwardVPTPosition();
12295 return Error(Loc,
"expected expression following directive");
12296 if (parseMany(parseOne))
12303bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
12306 getTargetStreamer().emitCurrentConstantPool();
12310bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
12311 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12317 getStreamer().initSections(getSTI());
12318 Section = getStreamer().getCurrentSectionOnly();
12321 assert(Section &&
"must have section to emit alignment");
12322 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12323 getStreamer().emitCodeAlignment(
Align(2), getSTI());
12325 getStreamer().emitValueToAlignment(
Align(2));
12332bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
12333 MCAsmParser &Parser = getParser();
12334 bool HasExistingPersonality = UC.hasPersonality();
12336 const MCExpr *IndexExpression;
12342 UC.recordPersonalityIndex(L);
12344 if (!UC.hasFnStart()) {
12345 return Error(L,
".fnstart must precede .personalityindex directive");
12347 if (UC.cantUnwind()) {
12348 Error(L,
".personalityindex cannot be used with .cantunwind");
12349 UC.emitCantUnwindLocNotes();
12352 if (UC.hasHandlerData()) {
12353 Error(L,
".personalityindex must precede .handlerdata directive");
12354 UC.emitHandlerDataLocNotes();
12357 if (HasExistingPersonality) {
12358 Error(L,
"multiple personality directives");
12359 UC.emitPersonalityLocNotes();
12365 return Error(IndexLoc,
"index must be a constant number");
12367 return Error(IndexLoc,
12368 "personality routine index should be in range [0-3]");
12370 getTargetStreamer().emitPersonalityIndex(
CE->getValue());
12376bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
12377 MCAsmParser &Parser = getParser();
12378 int64_t StackOffset;
12379 const MCExpr *OffsetExpr;
12380 SMLoc OffsetLoc = getLexer().
getLoc();
12382 if (!UC.hasFnStart())
12383 return Error(L,
".fnstart must precede .unwind_raw directives");
12384 if (getParser().parseExpression(OffsetExpr))
12385 return Error(OffsetLoc,
"expected expression");
12389 return Error(OffsetLoc,
"offset must be a constant");
12391 StackOffset =
CE->getValue();
12398 auto parseOne = [&]() ->
bool {
12399 const MCExpr *OE =
nullptr;
12400 SMLoc OpcodeLoc = getLexer().getLoc();
12403 OpcodeLoc,
"expected opcode expression"))
12407 return Error(OpcodeLoc,
"opcode value must be a constant");
12408 const int64_t Opcode = OC->
getValue();
12409 if (Opcode & ~0xff)
12410 return Error(OpcodeLoc,
"invalid opcode");
12416 SMLoc OpcodeLoc = getLexer().getLoc();
12418 return Error(OpcodeLoc,
"expected opcode expression");
12419 if (parseMany(parseOne))
12422 getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
12428bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
12429 MCAsmParser &Parser = getParser();
12432 return TokError(
"expected variable after '.tlsdescseq' directive");
12442 getTargetStreamer().annotateTLSDescriptorSequence(SRE);
12448bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
12449 MCAsmParser &Parser = getParser();
12450 if (!UC.hasFnStart())
12451 return Error(L,
".fnstart must precede .movsp directives");
12452 if (UC.getFPReg() != ARM::SP)
12453 return Error(L,
"unexpected .movsp directive");
12456 MCRegister
SPReg = tryParseRegister();
12458 return Error(SPRegLoc,
"register expected");
12460 return Error(SPRegLoc,
"sp and pc are not permitted in .movsp directive");
12467 const MCExpr *OffsetExpr;
12471 return Error(OffsetLoc,
"malformed offset expression");
12475 return Error(OffsetLoc,
"offset must be an immediate constant");
12484 UC.saveFPReg(
SPReg);
12491bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
12492 MCAsmParser &Parser = getParser();
12494 return Error(getLexer().getLoc(),
"unexpected token");
12502 if (ID == ARM::ArchKind::INVALID)
12503 return Error(ArchLoc,
"unknown architecture '" + Arch +
"'");
12507 getTargetStreamer().emitObjectArch(ID);
12513bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
12518 const MCSection *
Section = getStreamer().getCurrentSectionOnly();
12519 assert(Section &&
"must have section to emit alignment");
12520 if (
getContext().getAsmInfo().useCodeAlign(*Section))
12521 getStreamer().emitCodeAlignment(
Align(4), getSTI(), 0);
12523 getStreamer().emitValueToAlignment(
Align(4), 0, 1, 0);
12531bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
12532 MCAsmParser &Parser = getParser();
12536 "expected identifier after '.thumb_set'") ||
12541 const MCExpr *
Value;
12543 Parser, Sym,
Value))
12546 getTargetStreamer().emitThumbSet(Sym,
Value);
12553bool ARMAsmParser::parseDirectiveSEHAllocStack(SMLoc L,
bool Wide) {
12555 if (parseImmExpr(
Size))
12557 getTargetStreamer().emitARMWinCFIAllocStack(
Size, Wide);
12564bool ARMAsmParser::parseDirectiveSEHSaveRegs(SMLoc L,
bool Wide) {
12567 if (parseRegisterList(
Operands) || parseEOL())
12569 ARMOperand &
Op = (ARMOperand &)*
Operands[0];
12570 if (!
Op.isRegList())
12571 return Error(L,
".seh_save_regs{_w} expects GPR registers");
12572 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12574 for (
size_t i = 0; i < RegList.
size(); ++i) {
12579 return Error(L,
".seh_save_regs{_w} can't include SP");
12580 assert(
Reg < 16U &&
"Register out of range");
12581 unsigned Bit = (1u <<
Reg);
12584 if (!Wide && (Mask & 0x1f00) != 0)
12586 ".seh_save_regs cannot save R8-R12, needs .seh_save_regs_w");
12587 getTargetStreamer().emitARMWinCFISaveRegMask(Mask, Wide);
12593bool ARMAsmParser::parseDirectiveSEHSaveSP(SMLoc L) {
12594 MCRegister
Reg = tryParseRegister();
12596 return Error(L,
"expected GPR");
12598 if (Index > 14 || Index == 13)
12599 return Error(L,
"invalid register for .seh_save_sp");
12600 getTargetStreamer().emitARMWinCFISaveSP(Index);
12606bool ARMAsmParser::parseDirectiveSEHSaveFRegs(SMLoc L) {
12609 if (parseRegisterList(
Operands) || parseEOL())
12611 ARMOperand &
Op = (ARMOperand &)*
Operands[0];
12612 if (!
Op.isDPRRegList())
12613 return Error(L,
".seh_save_fregs expects DPR registers");
12614 const SmallVectorImpl<MCRegister> &RegList =
Op.getRegList();
12616 for (
size_t i = 0; i < RegList.
size(); ++i) {
12618 assert(
Reg < 32U &&
"Register out of range");
12619 unsigned Bit = (1u <<
Reg);
12624 return Error(L,
".seh_save_fregs missing registers");
12626 unsigned First = 0;
12627 while ((Mask & 1) == 0) {
12631 if (((Mask + 1) & Mask) != 0)
12633 ".seh_save_fregs must take a contiguous range of registers");
12635 while ((Mask & 2) != 0) {
12640 return Error(L,
".seh_save_fregs must be all d0-d15 or d16-d31");
12641 getTargetStreamer().emitARMWinCFISaveFRegs(
First,
Last);
12647bool ARMAsmParser::parseDirectiveSEHSaveLR(SMLoc L) {
12649 if (parseImmExpr(
Offset))
12651 getTargetStreamer().emitARMWinCFISaveLR(
Offset);
12658bool ARMAsmParser::parseDirectiveSEHPrologEnd(SMLoc L,
bool Fragment) {
12659 getTargetStreamer().emitARMWinCFIPrologEnd(Fragment);
12666bool ARMAsmParser::parseDirectiveSEHNop(SMLoc L,
bool Wide) {
12667 getTargetStreamer().emitARMWinCFINop(Wide);
12674bool ARMAsmParser::parseDirectiveSEHEpilogStart(SMLoc L,
bool Condition) {
12677 MCAsmParser &Parser = getParser();
12679 const AsmToken &Tok = Parser.
getTok();
12681 return Error(S,
".seh_startepilogue_cond missing condition");
12684 return Error(S,
"invalid condition");
12688 getTargetStreamer().emitARMWinCFIEpilogStart(CC);
12694bool ARMAsmParser::parseDirectiveSEHEpilogEnd(SMLoc L) {
12695 getTargetStreamer().emitARMWinCFIEpilogEnd();
12701bool ARMAsmParser::parseDirectiveSEHCustom(SMLoc L) {
12702 unsigned Opcode = 0;
12705 if (parseImmExpr(Byte))
12707 if (Byte > 0xff || Byte < 0)
12708 return Error(L,
"Invalid byte value in .seh_custom");
12709 if (Opcode > 0x00ffffff)
12710 return Error(L,
"Too many bytes in .seh_custom");
12713 Opcode = (Opcode << 8) | Byte;
12715 getTargetStreamer().emitARMWinCFICustom(Opcode);
12727#define GET_REGISTER_MATCHER
12728#define GET_SUBTARGET_FEATURE_NAME
12729#define GET_MATCHER_IMPLEMENTATION
12730#define GET_MNEMONIC_SPELL_CHECKER
12731#include "ARMGenAsmMatcher.inc"
12737ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
12738 switch (MatchError) {
12741 return hasV8Ops() ?
"operand must be a register in range [r0, r14]"
12742 :
"operand must be a register in range [r0, r12] or r14";
12745 return hasD32() ?
"operand must be a register in range [d0, d31]"
12746 :
"operand must be a register in range [d0, d15]";
12747 case Match_DPR_RegList:
12748 return hasD32() ?
"operand must be a list of registers in range [d0, d31]"
12749 :
"operand must be a list of registers in range [d0, d15]";
12753 return getMatchKindDiag(MatchError);
12761ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12762 SmallVectorImpl<NearMissMessage> &NearMissesOut,
12776 std::multimap<unsigned, unsigned> OperandMissesSeen;
12777 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
12778 bool ReportedTooFewOperands =
false;
12784 for (NearMissInfo &
I :
reverse(NearMissesIn)) {
12785 switch (
I.getKind()) {
12788 ((ARMOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
12789 const char *OperandDiag =
12790 getCustomOperandDiag((ARMMatchResultTy)
I.getOperandError());
12797 unsigned DupCheckMatchClass = OperandDiag ?
I.getOperandClass() : ~0
U;
12798 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
12799 if (std::any_of(PrevReports.first, PrevReports.second,
12800 [DupCheckMatchClass](
12801 const std::pair<unsigned, unsigned> Pair) {
12802 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
12803 return Pair.second == DupCheckMatchClass;
12805 return isSubclass((MatchClassKind)DupCheckMatchClass,
12806 (MatchClassKind)Pair.second);
12809 OperandMissesSeen.insert(
12810 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
12812 NearMissMessage Message;
12813 Message.Loc = OperandLoc;
12815 Message.Message = OperandDiag;
12816 }
else if (
I.getOperandClass() == InvalidMatchClass) {
12817 Message.Message =
"too many operands for instruction";
12819 Message.Message =
"invalid operand for instruction";
12821 dbgs() <<
"Missing diagnostic string for operand class "
12822 << getMatchClassName((MatchClassKind)
I.getOperandClass())
12823 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
12824 <<
", opcode " << MII.getName(
I.getOpcode()) <<
"\n");
12830 const FeatureBitset &MissingFeatures =
I.getFeatures();
12832 if (FeatureMissesSeen.
count(MissingFeatures))
12834 FeatureMissesSeen.
insert(MissingFeatures);
12838 if (MissingFeatures.
test(Feature_IsARMBit) && !hasARM())
12842 if (
isThumb() && MissingFeatures.
test(Feature_IsARMBit) &&
12843 MissingFeatures.
count() > 1)
12845 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumbBit) &&
12846 MissingFeatures.
count() > 1)
12848 if (!
isThumb() && MissingFeatures.
test(Feature_IsThumb2Bit) &&
12849 (MissingFeatures & ~FeatureBitset({Feature_IsThumb2Bit,
12850 Feature_IsThumbBit})).any())
12852 if (isMClass() && MissingFeatures.
test(Feature_HasNEONBit))
12855 NearMissMessage Message;
12856 Message.Loc = IDLoc;
12857 raw_svector_ostream OS(Message.Message);
12859 OS <<
"instruction requires:";
12860 for (
unsigned Feature : MissingFeatures)
12868 NearMissMessage Message;
12869 Message.Loc = IDLoc;
12870 switch (
I.getPredicateError()) {
12871 case Match_RequiresNotITBlock:
12872 Message.Message =
"flag setting instruction only valid outside IT block";
12874 case Match_RequiresITBlock:
12875 Message.Message =
"instruction only valid inside IT block";
12877 case Match_RequiresV6:
12878 Message.Message =
"instruction variant requires ARMv6 or later";
12880 case Match_RequiresThumb2:
12881 Message.Message =
"instruction variant requires Thumb2";
12883 case Match_RequiresV8:
12884 Message.Message =
"instruction variant requires ARMv8 or later";
12886 case Match_RequiresFlagSetting:
12887 Message.Message =
"no flag-preserving variant of this instruction available";
12889 case Match_InvalidTiedOperand: {
12890 ARMOperand &
Op =
static_cast<ARMOperand &
>(*
Operands[0]);
12891 if (
Op.isToken() &&
Op.getToken() ==
"mul") {
12892 Message.Message =
"destination register must match a source register";
12893 Message.Loc =
Operands[MnemonicOpsEndInd]->getStartLoc();
12899 case Match_InvalidOperand:
12900 Message.Message =
"invalid operand for instruction";
12910 if (!ReportedTooFewOperands) {
12911 SMLoc EndLoc = ((ARMOperand &)*
Operands.back()).getEndLoc();
12913 EndLoc, StringRef(
"too few operands for instruction")});
12914 ReportedTooFewOperands =
true;
12926void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
12929 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
12934 Error(IDLoc,
"invalid instruction");
12935 }
else if (
Messages.size() == 1) {
12937 Error(Messages[0].Loc, Messages[0].Message);
12941 Error(IDLoc,
"invalid instruction, any one of the following would fix this:");
12942 for (
auto &M : Messages) {
12948bool ARMAsmParser::enableArchExtFeature(StringRef Name, SMLoc &ExtLoc) {
12952 static const struct {
12954 const FeatureBitset ArchCheck;
12955 const FeatureBitset Features;
12957 {
ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC}},
12959 {Feature_HasV8Bit},
12960 {ARM::FeatureAES, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12962 {Feature_HasV8Bit},
12963 {ARM::FeatureSHA2, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12965 {Feature_HasV8Bit},
12966 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8}},
12968 {Feature_HasV8_1MMainlineBit},
12969 {ARM::HasMVEFloatOps}},
12971 {Feature_HasV8Bit},
12972 {ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12974 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12975 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM}},
12977 {Feature_HasV7Bit, Feature_IsNotMClassBit},
12980 {Feature_HasV8Bit},
12981 {ARM::FeatureNEON, ARM::FeatureVFP2_SP, ARM::FeatureFPARMv8}},
12982 {
ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone}},
12984 {
ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization}},
12986 {Feature_HasV8_2aBit},
12987 {ARM::FeatureFPARMv8, ARM::FeatureFullFP16}},
12988 {
ARM::AEK_RAS, {Feature_HasV8Bit}, {ARM::FeatureRAS}},
12989 {
ARM::AEK_LOB, {Feature_HasV8_1MMainlineBit}, {ARM::FeatureLOB}},
12990 {
ARM::AEK_PACBTI, {Feature_HasV8_1MMainlineBit}, {ARM::FeaturePACBTI}},
12998 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
13001 return Error(ExtLoc,
"unknown architectural extension: " + Name);
13008 return Error(ExtLoc,
"unsupported architectural extension: " + Name);
13011 return Error(ExtLoc,
"architectural extension '" + Name +
13013 "allowed for the current base architecture");
13015 MCSubtargetInfo &STI = copySTI();
13016 if (EnableFeature) {
13021 FeatureBitset Features = ComputeAvailableFeatures(STI.
getFeatureBits());
13022 setAvailableFeatures(Features);
13030bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
13032 MCAsmParser &Parser = getParser();
13035 return Error(getLexer().getLoc(),
"expected architecture extension name");
13044 if (Name ==
"nocrypto") {
13045 enableArchExtFeature(
"nosha2", ExtLoc);
13046 enableArchExtFeature(
"noaes", ExtLoc);
13049 if (enableArchExtFeature(Name, ExtLoc))
13052 return Error(ExtLoc,
"unknown architectural extension: " + Name);
13057unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
13059 ARMOperand &
Op =
static_cast<ARMOperand &
>(AsmOp);
13068 if (
CE->getValue() == 0)
13069 return Match_Success;
13074 if (
CE->getValue() == 8)
13075 return Match_Success;
13080 if (
CE->getValue() == 16)
13081 return Match_Success;
13085 const MCExpr *SOExpr =
Op.getImm();
13087 if (!SOExpr->evaluateAsAbsolute(
Value))
13088 return Match_Success;
13089 assert((
Value >= std::numeric_limits<int32_t>::min() &&
13090 Value <= std::numeric_limits<uint32_t>::max()) &&
13091 "expression value must be representable in 32 bits");
13095 if (hasV8Ops() &&
Op.isReg() &&
Op.getReg() == ARM::SP)
13096 return Match_Success;
13099 return Match_InvalidOperand;
13102bool ARMAsmParser::isMnemonicVPTPredicable(StringRef Mnemonic,
13103 StringRef ExtraToken) {
13107 if (MS.isVPTPredicableCDEInstr(Mnemonic) ||
13108 (Mnemonic.
starts_with(
"vldrh") && Mnemonic !=
"vldrhi") ||
13110 !(ExtraToken ==
".f16" || ExtraToken ==
".32" || ExtraToken ==
".16" ||
13111 ExtraToken ==
".8")) ||
13112 (Mnemonic.
starts_with(
"vrint") && Mnemonic !=
"vrintr") ||
13113 (Mnemonic.
starts_with(
"vstrh") && Mnemonic !=
"vstrhi"))
13116 const char *predicable_prefixes[] = {
13117 "vabav",
"vabd",
"vabs",
"vadc",
"vadd",
13118 "vaddlv",
"vaddv",
"vand",
"vbic",
"vbrsr",
13119 "vcadd",
"vcls",
"vclz",
"vcmla",
"vcmp",
13120 "vcmul",
"vctp",
"vcvt",
"vddup",
"vdup",
13121 "vdwdup",
"veor",
"vfma",
"vfmas",
"vfms",
13122 "vhadd",
"vhcadd",
"vhsub",
"vidup",
"viwdup",
13123 "vldrb",
"vldrd",
"vldrw",
"vmax",
"vmaxa",
13124 "vmaxav",
"vmaxnm",
"vmaxnma",
"vmaxnmav",
"vmaxnmv",
13125 "vmaxv",
"vmin",
"vminav",
"vminnm",
"vminnmav",
13126 "vminnmv",
"vminv",
"vmla",
"vmladav",
"vmlaldav",
13127 "vmlalv",
"vmlas",
"vmlav",
"vmlsdav",
"vmlsldav",
13128 "vmovlb",
"vmovlt",
"vmovnb",
"vmovnt",
"vmul",
13129 "vmvn",
"vneg",
"vorn",
"vorr",
"vpnot",
13130 "vpsel",
"vqabs",
"vqadd",
"vqdmladh",
"vqdmlah",
13131 "vqdmlash",
"vqdmlsdh",
"vqdmulh",
"vqdmull",
"vqmovn",
13132 "vqmovun",
"vqneg",
"vqrdmladh",
"vqrdmlah",
"vqrdmlash",
13133 "vqrdmlsdh",
"vqrdmulh",
"vqrshl",
"vqrshrn",
"vqrshrun",
13134 "vqshl",
"vqshrn",
"vqshrun",
"vqsub",
"vrev16",
13135 "vrev32",
"vrev64",
"vrhadd",
"vrmlaldavh",
"vrmlalvh",
13136 "vrmlsldavh",
"vrmulh",
"vrshl",
"vrshr",
"vrshrn",
13137 "vsbc",
"vshl",
"vshlc",
"vshll",
"vshr",
13138 "vshrn",
"vsli",
"vsri",
"vstrb",
"vstrd",
13141 return any_of(predicable_prefixes, [&Mnemonic](
const char *prefix) {
13146std::unique_ptr<ARMOperand> ARMAsmParser::defaultCondCodeOp() {
13147 return ARMOperand::CreateCondCode(
ARMCC::AL, SMLoc(), *
this);
13150std::unique_ptr<ARMOperand> ARMAsmParser::defaultCCOutOp() {
13151 return ARMOperand::CreateCCOut(0, SMLoc(), *
this);
13154std::unique_ptr<ARMOperand> ARMAsmParser::defaultVPTPredOp() {
13155 return ARMOperand::CreateVPTPred(
ARMVCC::None, SMLoc(), *
this);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
static SDValue getCondCode(SelectionDAG &DAG, AArch64CC::CondCode CC)
Like SelectionDAG::getCondCode(), but for AArch64 condition codes.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static std::string ARMMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing)
static bool instIsBreakpoint(const MCInst &Inst)
unsigned findCCOutInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isDataTypeToken(StringRef Tok)
}
static MCRegister getNextRegister(MCRegister Reg)
static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing)
unsigned getRegListInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
static bool isVectorPredicable(const MCInstrDesc &MCID)
static bool listContainsReg(const MCInst &Inst, unsigned OpNo, MCRegister Reg)
static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp)
MatchCoprocessorOperandName - Try to parse an coprocessor related instruction with a symbolic operand...
void removeCCOut(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo, MCRegister Reg, MCRegister HiReg, bool &containsReg)
static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMAsmParser()
Force static initialization.
static int findFirstVectorPredOperandIdx(const MCInstrDesc &MCID)
static bool isThumbI8Relocation(MCParsedAsmOperand &MCOp)
bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool insertNoDuplicates(SmallVectorImpl< std::pair< unsigned, MCRegister > > &Regs, unsigned Enc, MCRegister Reg)
static unsigned getMnemonicOpsEndInd(const OperandVector &Operands)
static bool isARMMCExpr(MCParsedAsmOperand &MCOp)
unsigned findCondCodeInd(const OperandVector &Operands, unsigned MnemonicOpsEndInd)
void removeVPTCondCode(OperandVector &Operands, unsigned &MnemonicOpsEndInd)
static bool isThumb(const MCSubtargetInfo &STI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static cl::opt< bool > AddBuildAttributes("csky-add-build-attributes", cl::init(true))
static Register getFPReg(const CSKYSubtarget &STI)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_EXTERNAL_VISIBILITY
Value * getPointer(Value *Ptr)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool containsReg(SmallSetVector< Register, 32 > LocalDefsV, const BitVector &LocalDefsP, Register Reg, const TargetRegisterInfo *TRI)
Check if target reg is contained in given lists, which are: LocalDefsV as given list for virtual regs...
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr MCPhysReg FPReg
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI Pre allocate WWM Registers
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static cl::opt< ExtensionSet, false, SPIRVExtensionsParser > Extensions("spirv-ext", cl::desc("Specify list of enabled SPIR-V extensions"))
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=ARM::NoRegAltName)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Implements a dense probed hash-table based set.
Base class for user error types.
Container class for subtarget features.
constexpr bool test(unsigned I) const
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
bool parseToken(AsmToken::TokenKind T, const Twine &Msg="unexpected token")
virtual bool parseEscapedString(std::string &Data)=0
Parse the current token as a string which may include escaped characters and return the string conten...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual void Note(SMLoc L, const Twine &Msg, SMRange Range={})=0
Emit a note at the location L, with the message Msg.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
@ Constant
Constant expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isIndirectBranch() const
Return true if this is an indirect branch, such as a branch through a register.
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
LLVM_ABI bool hasDefOfPhysReg(const MCInst &MI, MCRegister Reg, const MCRegisterInfo &RI) const
Return true if this instruction defines the specified physical register, either explicitly or implici...
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
bool isCall() const
Return true if the instruction is a call.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
bool isReturn() const
Return true if the instruction is a return.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getID() const
getID() - Return the register class ID number.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
const FeatureBitset & ApplyFeatureFlag(StringRef FS)
Apply a feature flag and return the re-computed feature bits, including all feature bits implied by t...
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
const FeatureBitset & ClearFeatureBitsTransitively(const FeatureBitset &FB)
const FeatureBitset & SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Target specific streamer interface.
MCStreamer & getStreamer()
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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,...