LCOV - code coverage report
Current view: top level - lib/Target/ARM/AsmParser - ARMAsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 3273 4350 75.2 %
Date: 2018-10-20 13:21:21 Functions: 154 335 46.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions -------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "ARMFeatures.h"
      11             : #include "Utils/ARMBaseInfo.h"
      12             : #include "MCTargetDesc/ARMAddressingModes.h"
      13             : #include "MCTargetDesc/ARMBaseInfo.h"
      14             : #include "MCTargetDesc/ARMMCExpr.h"
      15             : #include "MCTargetDesc/ARMMCTargetDesc.h"
      16             : #include "llvm/ADT/APFloat.h"
      17             : #include "llvm/ADT/APInt.h"
      18             : #include "llvm/ADT/None.h"
      19             : #include "llvm/ADT/STLExtras.h"
      20             : #include "llvm/ADT/SmallSet.h"
      21             : #include "llvm/ADT/SmallVector.h"
      22             : #include "llvm/ADT/StringMap.h"
      23             : #include "llvm/ADT/StringRef.h"
      24             : #include "llvm/ADT/StringSwitch.h"
      25             : #include "llvm/ADT/Triple.h"
      26             : #include "llvm/ADT/Twine.h"
      27             : #include "llvm/MC/MCContext.h"
      28             : #include "llvm/MC/MCExpr.h"
      29             : #include "llvm/MC/MCInst.h"
      30             : #include "llvm/MC/MCInstrDesc.h"
      31             : #include "llvm/MC/MCInstrInfo.h"
      32             : #include "llvm/MC/MCObjectFileInfo.h"
      33             : #include "llvm/MC/MCParser/MCAsmLexer.h"
      34             : #include "llvm/MC/MCParser/MCAsmParser.h"
      35             : #include "llvm/MC/MCParser/MCAsmParserExtension.h"
      36             : #include "llvm/MC/MCParser/MCAsmParserUtils.h"
      37             : #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
      38             : #include "llvm/MC/MCParser/MCTargetAsmParser.h"
      39             : #include "llvm/MC/MCRegisterInfo.h"
      40             : #include "llvm/MC/MCSection.h"
      41             : #include "llvm/MC/MCStreamer.h"
      42             : #include "llvm/MC/MCSubtargetInfo.h"
      43             : #include "llvm/MC/MCSymbol.h"
      44             : #include "llvm/MC/SubtargetFeature.h"
      45             : #include "llvm/Support/ARMBuildAttributes.h"
      46             : #include "llvm/Support/ARMEHABI.h"
      47             : #include "llvm/Support/Casting.h"
      48             : #include "llvm/Support/CommandLine.h"
      49             : #include "llvm/Support/Compiler.h"
      50             : #include "llvm/Support/ErrorHandling.h"
      51             : #include "llvm/Support/MathExtras.h"
      52             : #include "llvm/Support/SMLoc.h"
      53             : #include "llvm/Support/TargetParser.h"
      54             : #include "llvm/Support/TargetRegistry.h"
      55             : #include "llvm/Support/raw_ostream.h"
      56             : #include <algorithm>
      57             : #include <cassert>
      58             : #include <cstddef>
      59             : #include <cstdint>
      60             : #include <iterator>
      61             : #include <limits>
      62             : #include <memory>
      63             : #include <string>
      64             : #include <utility>
      65             : #include <vector>
      66             : 
      67             : #define DEBUG_TYPE "asm-parser"
      68             : 
      69             : using namespace llvm;
      70             : 
      71             : namespace {
      72             : 
      73             : enum class ImplicitItModeTy { Always, Never, ARMOnly, ThumbOnly };
      74             : 
      75             : static cl::opt<ImplicitItModeTy> ImplicitItMode(
      76             :     "arm-implicit-it", cl::init(ImplicitItModeTy::ARMOnly),
      77             :     cl::desc("Allow conditional instructions outdside of an IT block"),
      78             :     cl::values(clEnumValN(ImplicitItModeTy::Always, "always",
      79             :                           "Accept in both ISAs, emit implicit ITs in Thumb"),
      80             :                clEnumValN(ImplicitItModeTy::Never, "never",
      81             :                           "Warn in ARM, reject in Thumb"),
      82             :                clEnumValN(ImplicitItModeTy::ARMOnly, "arm",
      83             :                           "Accept in ARM, reject in Thumb"),
      84             :                clEnumValN(ImplicitItModeTy::ThumbOnly, "thumb",
      85             :                           "Warn in ARM, emit implicit ITs in Thumb")));
      86             : 
      87             : static cl::opt<bool> AddBuildAttributes("arm-add-build-attributes",
      88             :                                         cl::init(false));
      89             : 
      90             : enum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
      91             : 
      92             : class UnwindContext {
      93             :   using Locs = SmallVector<SMLoc, 4>;
      94             : 
      95             :   MCAsmParser &Parser;
      96             :   Locs FnStartLocs;
      97             :   Locs CantUnwindLocs;
      98             :   Locs PersonalityLocs;
      99             :   Locs PersonalityIndexLocs;
     100             :   Locs HandlerDataLocs;
     101             :   int FPReg;
     102             : 
     103             : public:
     104        1317 :   UnwindContext(MCAsmParser &P) : Parser(P), FPReg(ARM::SP) {}
     105             : 
     106         897 :   bool hasFnStart() const { return !FnStartLocs.empty(); }
     107         169 :   bool cantUnwind() const { return !CantUnwindLocs.empty(); }
     108         277 :   bool hasHandlerData() const { return !HandlerDataLocs.empty(); }
     109             : 
     110             :   bool hasPersonality() const {
     111         150 :     return !(PersonalityLocs.empty() && PersonalityIndexLocs.empty());
     112             :   }
     113             : 
     114         230 :   void recordFnStart(SMLoc L) { FnStartLocs.push_back(L); }
     115          56 :   void recordCantUnwind(SMLoc L) { CantUnwindLocs.push_back(L); }
     116          78 :   void recordPersonality(SMLoc L) { PersonalityLocs.push_back(L); }
     117          77 :   void recordHandlerData(SMLoc L) { HandlerDataLocs.push_back(L); }
     118          16 :   void recordPersonalityIndex(SMLoc L) { PersonalityIndexLocs.push_back(L); }
     119             : 
     120          41 :   void saveFPReg(int Reg) { FPReg = Reg; }
     121           0 :   int getFPReg() const { return FPReg; }
     122             : 
     123           1 :   void emitFnStartLocNotes() const {
     124           1 :     for (Locs::const_iterator FI = FnStartLocs.begin(), FE = FnStartLocs.end();
     125           2 :          FI != FE; ++FI)
     126           2 :       Parser.Note(*FI, ".fnstart was specified here");
     127           1 :   }
     128             : 
     129           3 :   void emitCantUnwindLocNotes() const {
     130           3 :     for (Locs::const_iterator UI = CantUnwindLocs.begin(),
     131           6 :                               UE = CantUnwindLocs.end(); UI != UE; ++UI)
     132           6 :       Parser.Note(*UI, ".cantunwind was specified here");
     133           3 :   }
     134             : 
     135           3 :   void emitHandlerDataLocNotes() const {
     136           3 :     for (Locs::const_iterator HI = HandlerDataLocs.begin(),
     137           6 :                               HE = HandlerDataLocs.end(); HI != HE; ++HI)
     138           6 :       Parser.Note(*HI, ".handlerdata was specified here");
     139           3 :   }
     140             : 
     141           6 :   void emitPersonalityLocNotes() const {
     142             :     for (Locs::const_iterator PI = PersonalityLocs.begin(),
     143             :                               PE = PersonalityLocs.end(),
     144             :                               PII = PersonalityIndexLocs.begin(),
     145             :                               PIE = PersonalityIndexLocs.end();
     146          19 :          PI != PE || PII != PIE;) {
     147          13 :       if (PI != PE && (PII == PIE || PI->getPointer() < PII->getPointer()))
     148          20 :         Parser.Note(*PI++, ".personality was specified here");
     149           3 :       else if (PII != PIE && (PI == PE || PII->getPointer() < PI->getPointer()))
     150           6 :         Parser.Note(*PII++, ".personalityindex was specified here");
     151             :       else
     152           0 :         llvm_unreachable(".personality and .personalityindex cannot be "
     153             :                          "at the same location");
     154             :     }
     155           6 :   }
     156             : 
     157         455 :   void reset() {
     158         455 :     FnStartLocs = Locs();
     159         455 :     CantUnwindLocs = Locs();
     160         455 :     PersonalityLocs = Locs();
     161         455 :     HandlerDataLocs = Locs();
     162         455 :     PersonalityIndexLocs = Locs();
     163         455 :     FPReg = ARM::SP;
     164         455 :   }
     165             : };
     166             : 
     167             : class ARMAsmParser : public MCTargetAsmParser {
     168             :   const MCRegisterInfo *MRI;
     169             :   UnwindContext UC;
     170             : 
     171             :   ARMTargetStreamer &getTargetStreamer() {
     172             :     assert(getParser().getStreamer().getTargetStreamer() &&
     173             :            "do not have a target streamer");
     174        1194 :     MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
     175             :     return static_cast<ARMTargetStreamer &>(TS);
     176             :   }
     177             : 
     178             :   // Map of register aliases registers via the .req directive.
     179             :   StringMap<unsigned> RegisterReqs;
     180             : 
     181             :   bool NextSymbolIsThumb;
     182             : 
     183           0 :   bool useImplicitITThumb() const {
     184       12566 :     return ImplicitItMode == ImplicitItModeTy::Always ||
     185           0 :            ImplicitItMode == ImplicitItModeTy::ThumbOnly;
     186             :   }
     187             : 
     188           0 :   bool useImplicitITARM() const {
     189        7486 :     return ImplicitItMode == ImplicitItModeTy::Always ||
     190           0 :            ImplicitItMode == ImplicitItModeTy::ARMOnly;
     191             :   }
     192             : 
     193             :   struct {
     194             :     ARMCC::CondCodes Cond;    // Condition for IT block.
     195             :     unsigned Mask:4;          // Condition mask for instructions.
     196             :                               // Starting at first 1 (from lsb).
     197             :                               //   '1'  condition as indicated in IT.
     198             :                               //   '0'  inverse of condition (else).
     199             :                               // Count of instructions in IT block is
     200             :                               // 4 - trailingzeroes(mask)
     201             :                               // Note that this does not have the same encoding
     202             :                               // as in the IT instruction, which also depends
     203             :                               // on the low bit of the condition code.
     204             : 
     205             :     unsigned CurPosition;     // Current position in parsing of IT
     206             :                               // block. In range [0,4], with 0 being the IT
     207             :                               // instruction itself. Initialized according to
     208             :                               // count of instructions in block.  ~0U if no
     209             :                               // active IT block.
     210             : 
     211             :     bool IsExplicit;          // true  - The IT instruction was present in the
     212             :                               //         input, we should not modify it.
     213             :                               // false - The IT instruction was added
     214             :                               //         implicitly, we can extend it if that
     215             :                               //         would be legal.
     216             :   } ITState;
     217             : 
     218             :   SmallVector<MCInst, 4> PendingConditionalInsts;
     219             : 
     220       13742 :   void flushPendingInstructions(MCStreamer &Out) override {
     221             :     if (!inImplicitITBlock()) {
     222             :       assert(PendingConditionalInsts.size() == 0);
     223       13648 :       return;
     224             :     }
     225             : 
     226             :     // Emit the IT instruction
     227             :     unsigned Mask = getITMaskEncoding();
     228             :     MCInst ITInst;
     229             :     ITInst.setOpcode(ARM::t2IT);
     230          94 :     ITInst.addOperand(MCOperand::createImm(ITState.Cond));
     231          94 :     ITInst.addOperand(MCOperand::createImm(Mask));
     232          94 :     Out.EmitInstruction(ITInst, getSTI());
     233             : 
     234             :     // Emit the conditonal instructions
     235             :     assert(PendingConditionalInsts.size() <= 4);
     236         208 :     for (const MCInst &Inst : PendingConditionalInsts) {
     237         114 :       Out.EmitInstruction(Inst, getSTI());
     238             :     }
     239          94 :     PendingConditionalInsts.clear();
     240             : 
     241             :     // Clear the IT state
     242          94 :     ITState.Mask = 0;
     243          94 :     ITState.CurPosition = ~0U;
     244             :   }
     245             : 
     246          52 :   bool inITBlock() { return ITState.CurPosition != ~0U; }
     247       24248 :   bool inExplicitITBlock() { return inITBlock() && ITState.IsExplicit; }
     248       13878 :   bool inImplicitITBlock() { return inITBlock() && !ITState.IsExplicit; }
     249             : 
     250             :   bool lastInITBlock() {
     251        3014 :     return ITState.CurPosition == 4 - countTrailingZeros(ITState.Mask);
     252             :   }
     253             : 
     254             :   void forwardITPosition() {
     255       21193 :     if (!inITBlock()) return;
     256             :     // Move to the next instruction in the IT block, if there is one. If not,
     257             :     // mark the block as done, except for implicit IT blocks, which we leave
     258             :     // open until we find an instruction that can't be added to it.
     259        5931 :     unsigned TZ = countTrailingZeros(ITState.Mask);
     260        5931 :     if (++ITState.CurPosition == 5 - TZ && ITState.IsExplicit)
     261        2763 :       ITState.CurPosition = ~0U; // Done with the IT block after this.
     262             :   }
     263             : 
     264             :   // Rewind the state of the current IT block, removing the last slot from it.
     265             :   void rewindImplicitITPosition() {
     266             :     assert(inImplicitITBlock());
     267             :     assert(ITState.CurPosition > 1);
     268           9 :     ITState.CurPosition--;
     269           9 :     unsigned TZ = countTrailingZeros(ITState.Mask);
     270             :     unsigned NewMask = 0;
     271           9 :     NewMask |= ITState.Mask & (0xC << TZ);
     272           9 :     NewMask |= 0x2 << TZ;
     273           9 :     ITState.Mask = NewMask;
     274             :   }
     275             : 
     276             :   // Rewind the state of the current IT block, removing the last slot from it.
     277             :   // If we were at the first slot, this closes the IT block.
     278           0 :   void discardImplicitITBlock() {
     279             :     assert(inImplicitITBlock());
     280             :     assert(ITState.CurPosition == 1);
     281           0 :     ITState.CurPosition = ~0U;
     282           0 :   }
     283             : 
     284             :   // Return the low-subreg of a given Q register.
     285           0 :   unsigned getDRegFromQReg(unsigned QReg) const {
     286           0 :     return MRI->getSubReg(QReg, ARM::dsub_0);
     287             :   }
     288             : 
     289             :   // Get the encoding of the IT mask, as it will appear in an IT instruction.
     290             :   unsigned getITMaskEncoding() {
     291             :     assert(inITBlock());
     292          94 :     unsigned Mask = ITState.Mask;
     293        2863 :     unsigned TZ = countTrailingZeros(Mask);
     294        2863 :     if ((ITState.Cond & 1) == 0) {
     295             :       assert(Mask && TZ <= 3 && "illegal IT mask value!");
     296        2748 :       Mask ^= (0xE << TZ) & 0xF;
     297             :     }
     298             :     return Mask;
     299             :   }
     300             : 
     301             :   // Get the condition code corresponding to the current IT block slot.
     302             :   ARMCC::CondCodes currentITCond() {
     303             :     unsigned MaskBit;
     304          24 :     if (ITState.CurPosition == 1)
     305             :       MaskBit = 1;
     306             :     else
     307         337 :       MaskBit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
     308             : 
     309        3198 :     return MaskBit ? ITState.Cond : ARMCC::getOppositeCondition(ITState.Cond);
     310             :   }
     311             : 
     312             :   // Invert the condition of the current IT block slot without changing any
     313             :   // other slots in the same block.
     314             :   void invertCurrentITCondition() {
     315           5 :     if (ITState.CurPosition == 1) {
     316           0 :       ITState.Cond = ARMCC::getOppositeCondition(ITState.Cond);
     317             :     } else {
     318           5 :       ITState.Mask ^= 1 << (5 - ITState.CurPosition);
     319             :     }
     320             :   }
     321             : 
     322             :   // Returns true if the current IT block is full (all 4 slots used).
     323             :   bool isITBlockFull() {
     324         114 :     return inITBlock() && (ITState.Mask & 1);
     325             :   }
     326             : 
     327             :   // Extend the current implicit IT block to have one more slot with the given
     328             :   // condition code.
     329             :   void extendImplicitITBlock(ARMCC::CondCodes Cond) {
     330             :     assert(inImplicitITBlock());
     331             :     assert(!isITBlockFull());
     332             :     assert(Cond == ITState.Cond ||
     333             :            Cond == ARMCC::getOppositeCondition(ITState.Cond));
     334          29 :     unsigned TZ = countTrailingZeros(ITState.Mask);
     335             :     unsigned NewMask = 0;
     336             :     // Keep any existing condition bits.
     337          29 :     NewMask |= ITState.Mask & (0xE << TZ);
     338             :     // Insert the new condition bit.
     339          29 :     NewMask |= (Cond == ITState.Cond) << TZ;
     340             :     // Move the trailing 1 down one bit.
     341          29 :     NewMask |= 1 << (TZ - 1);
     342          29 :     ITState.Mask = NewMask;
     343             :   }
     344             : 
     345             :   // Create a new implicit IT block with a dummy condition code.
     346             :   void startImplicitITBlock() {
     347             :     assert(!inITBlock());
     348          94 :     ITState.Cond = ARMCC::AL;
     349          94 :     ITState.Mask = 8;
     350          94 :     ITState.CurPosition = 1;
     351          94 :     ITState.IsExplicit = false;
     352             :   }
     353             : 
     354             :   // Create a new explicit IT block with the given condition and mask. The mask
     355             :   // should be in the parsed format, with a 1 implying 't', regardless of the
     356             :   // low bit of the condition.
     357             :   void startExplicitITBlock(ARMCC::CondCodes Cond, unsigned Mask) {
     358             :     assert(!inITBlock());
     359        2769 :     ITState.Cond = Cond;
     360        2769 :     ITState.Mask = Mask;
     361        2769 :     ITState.CurPosition = 0;
     362        2769 :     ITState.IsExplicit = true;
     363             :   }
     364             : 
     365             :   void Note(SMLoc L, const Twine &Msg, SMRange Range = None) {
     366        2971 :     return getParser().Note(L, Msg, Range);
     367             :   }
     368             : 
     369             :   bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) {
     370        2165 :     return getParser().Warning(L, Msg, Range);
     371             :   }
     372             : 
     373             :   bool Error(SMLoc L, const Twine &Msg, SMRange Range = None) {
     374        5058 :     return getParser().Error(L, Msg, Range);
     375             :   }
     376             : 
     377             :   bool validatetLDMRegList(const MCInst &Inst, const OperandVector &Operands,
     378             :                            unsigned ListNo, bool IsARPop = false);
     379             :   bool validatetSTMRegList(const MCInst &Inst, const OperandVector &Operands,
     380             :                            unsigned ListNo);
     381             : 
     382             :   int tryParseRegister();
     383             :   bool tryParseRegisterWithWriteBack(OperandVector &);
     384             :   int tryParseShiftRegister(OperandVector &);
     385             :   bool parseRegisterList(OperandVector &);
     386             :   bool parseMemory(OperandVector &);
     387             :   bool parseOperand(OperandVector &, StringRef Mnemonic);
     388             :   bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
     389             :   bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
     390             :                               unsigned &ShiftAmount);
     391             :   bool parseLiteralValues(unsigned Size, SMLoc L);
     392             :   bool parseDirectiveThumb(SMLoc L);
     393             :   bool parseDirectiveARM(SMLoc L);
     394             :   bool parseDirectiveThumbFunc(SMLoc L);
     395             :   bool parseDirectiveCode(SMLoc L);
     396             :   bool parseDirectiveSyntax(SMLoc L);
     397             :   bool parseDirectiveReq(StringRef Name, SMLoc L);
     398             :   bool parseDirectiveUnreq(SMLoc L);
     399             :   bool parseDirectiveArch(SMLoc L);
     400             :   bool parseDirectiveEabiAttr(SMLoc L);
     401             :   bool parseDirectiveCPU(SMLoc L);
     402             :   bool parseDirectiveFPU(SMLoc L);
     403             :   bool parseDirectiveFnStart(SMLoc L);
     404             :   bool parseDirectiveFnEnd(SMLoc L);
     405             :   bool parseDirectiveCantUnwind(SMLoc L);
     406             :   bool parseDirectivePersonality(SMLoc L);
     407             :   bool parseDirectiveHandlerData(SMLoc L);
     408             :   bool parseDirectiveSetFP(SMLoc L);
     409             :   bool parseDirectivePad(SMLoc L);
     410             :   bool parseDirectiveRegSave(SMLoc L, bool IsVector);
     411             :   bool parseDirectiveInst(SMLoc L, char Suffix = '\0');
     412             :   bool parseDirectiveLtorg(SMLoc L);
     413             :   bool parseDirectiveEven(SMLoc L);
     414             :   bool parseDirectivePersonalityIndex(SMLoc L);
     415             :   bool parseDirectiveUnwindRaw(SMLoc L);
     416             :   bool parseDirectiveTLSDescSeq(SMLoc L);
     417             :   bool parseDirectiveMovSP(SMLoc L);
     418             :   bool parseDirectiveObjectArch(SMLoc L);
     419             :   bool parseDirectiveArchExtension(SMLoc L);
     420             :   bool parseDirectiveAlign(SMLoc L);
     421             :   bool parseDirectiveThumbSet(SMLoc L);
     422             : 
     423             :   StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
     424             :                           bool &CarrySetting, unsigned &ProcessorIMod,
     425             :                           StringRef &ITMask);
     426             :   void getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
     427             :                              bool &CanAcceptCarrySet,
     428             :                              bool &CanAcceptPredicationCode);
     429             : 
     430             :   void tryConvertingToTwoOperandForm(StringRef Mnemonic, bool CarrySetting,
     431             :                                      OperandVector &Operands);
     432             :   bool isThumb() const {
     433             :     // FIXME: Can tablegen auto-generate this?
     434      203371 :     return getSTI().getFeatureBits()[ARM::ModeThumb];
     435             :   }
     436             : 
     437       72445 :   bool isThumbOne() const {
     438       72445 :     return isThumb() && !getSTI().getFeatureBits()[ARM::FeatureThumb2];
     439             :   }
     440             : 
     441      168249 :   bool isThumbTwo() const {
     442      168249 :     return isThumb() && getSTI().getFeatureBits()[ARM::FeatureThumb2];
     443             :   }
     444             : 
     445             :   bool hasThumb() const {
     446         511 :     return getSTI().getFeatureBits()[ARM::HasV4TOps];
     447             :   }
     448             : 
     449             :   bool hasThumb2() const {
     450         316 :     return getSTI().getFeatureBits()[ARM::FeatureThumb2];
     451             :   }
     452             : 
     453             :   bool hasV6Ops() const {
     454          39 :     return getSTI().getFeatureBits()[ARM::HasV6Ops];
     455             :   }
     456             : 
     457             :   bool hasV6T2Ops() const {
     458          79 :     return getSTI().getFeatureBits()[ARM::HasV6T2Ops];
     459             :   }
     460             : 
     461             :   bool hasV6MOps() const {
     462        1000 :     return getSTI().getFeatureBits()[ARM::HasV6MOps];
     463             :   }
     464             : 
     465             :   bool hasV7Ops() const {
     466         997 :     return getSTI().getFeatureBits()[ARM::HasV7Ops];
     467             :   }
     468             : 
     469             :   bool hasV8Ops() const {
     470       15740 :     return getSTI().getFeatureBits()[ARM::HasV8Ops];
     471             :   }
     472             : 
     473             :   bool hasV8MBaseline() const {
     474         208 :     return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps];
     475             :   }
     476             : 
     477             :   bool hasV8MMainline() const {
     478             :     return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps];
     479             :   }
     480             : 
     481             :   bool has8MSecExt() const {
     482             :     return getSTI().getFeatureBits()[ARM::Feature8MSecExt];
     483             :   }
     484             : 
     485             :   bool hasARM() const {
     486         387 :     return !getSTI().getFeatureBits()[ARM::FeatureNoARM];
     487             :   }
     488             : 
     489             :   bool hasDSP() const {
     490             :     return getSTI().getFeatureBits()[ARM::FeatureDSP];
     491             :   }
     492             : 
     493             :   bool hasD16() const {
     494       50877 :     return getSTI().getFeatureBits()[ARM::FeatureD16];
     495             :   }
     496             : 
     497             :   bool hasV8_1aOps() const {
     498             :     return getSTI().getFeatureBits()[ARM::HasV8_1aOps];
     499             :   }
     500             : 
     501             :   bool hasRAS() const {
     502           2 :     return getSTI().getFeatureBits()[ARM::FeatureRAS];
     503             :   }
     504             : 
     505         257 :   void SwitchMode() {
     506         257 :     MCSubtargetInfo &STI = copySTI();
     507         257 :     uint64_t FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
     508             :     setAvailableFeatures(FB);
     509         257 :   }
     510             : 
     511             :   void FixModeAfterArchChange(bool WasThumb, SMLoc Loc);
     512             : 
     513             :   bool isMClass() const {
     514        2254 :     return getSTI().getFeatureBits()[ARM::FeatureMClass];
     515             :   }
     516             : 
     517             :   /// @name Auto-generated Match Functions
     518             :   /// {
     519             : 
     520             : #define GET_ASSEMBLER_HEADER
     521             : #include "ARMGenAsmMatcher.inc"
     522             : 
     523             :   /// }
     524             : 
     525             :   OperandMatchResultTy parseITCondCode(OperandVector &);
     526             :   OperandMatchResultTy parseCoprocNumOperand(OperandVector &);
     527             :   OperandMatchResultTy parseCoprocRegOperand(OperandVector &);
     528             :   OperandMatchResultTy parseCoprocOptionOperand(OperandVector &);
     529             :   OperandMatchResultTy parseMemBarrierOptOperand(OperandVector &);
     530             :   OperandMatchResultTy parseTraceSyncBarrierOptOperand(OperandVector &);
     531             :   OperandMatchResultTy parseInstSyncBarrierOptOperand(OperandVector &);
     532             :   OperandMatchResultTy parseProcIFlagsOperand(OperandVector &);
     533             :   OperandMatchResultTy parseMSRMaskOperand(OperandVector &);
     534             :   OperandMatchResultTy parseBankedRegOperand(OperandVector &);
     535             :   OperandMatchResultTy parsePKHImm(OperandVector &O, StringRef Op, int Low,
     536             :                                    int High);
     537             :   OperandMatchResultTy parsePKHLSLImm(OperandVector &O) {
     538          22 :     return parsePKHImm(O, "lsl", 0, 31);
     539             :   }
     540             :   OperandMatchResultTy parsePKHASRImm(OperandVector &O) {
     541          14 :     return parsePKHImm(O, "asr", 1, 32);
     542             :   }
     543             :   OperandMatchResultTy parseSetEndImm(OperandVector &);
     544             :   OperandMatchResultTy parseShifterImm(OperandVector &);
     545             :   OperandMatchResultTy parseRotImm(OperandVector &);
     546             :   OperandMatchResultTy parseModImm(OperandVector &);
     547             :   OperandMatchResultTy parseBitfield(OperandVector &);
     548             :   OperandMatchResultTy parsePostIdxReg(OperandVector &);
     549             :   OperandMatchResultTy parseAM3Offset(OperandVector &);
     550             :   OperandMatchResultTy parseFPImm(OperandVector &);
     551             :   OperandMatchResultTy parseVectorList(OperandVector &);
     552             :   OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index,
     553             :                                        SMLoc &EndLoc);
     554             : 
     555             :   // Asm Match Converter Methods
     556             :   void cvtThumbMultiply(MCInst &Inst, const OperandVector &);
     557             :   void cvtThumbBranches(MCInst &Inst, const OperandVector &);
     558             : 
     559             :   bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
     560             :   bool processInstruction(MCInst &Inst, const OperandVector &Ops, MCStreamer &Out);
     561             :   bool shouldOmitCCOutOperand(StringRef Mnemonic, OperandVector &Operands);
     562             :   bool shouldOmitPredicateOperand(StringRef Mnemonic, OperandVector &Operands);
     563             :   bool isITBlockTerminator(MCInst &Inst) const;
     564             :   void fixupGNULDRDAlias(StringRef Mnemonic, OperandVector &Operands);
     565             :   bool validateLDRDSTRD(MCInst &Inst, const OperandVector &Operands,
     566             :                         bool Load, bool ARMMode, bool Writeback);
     567             : 
     568             : public:
     569             :   enum ARMMatchResultTy {
     570             :     Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
     571             :     Match_RequiresNotITBlock,
     572             :     Match_RequiresV6,
     573             :     Match_RequiresThumb2,
     574             :     Match_RequiresV8,
     575             :     Match_RequiresFlagSetting,
     576             : #define GET_OPERAND_DIAGNOSTIC_TYPES
     577             : #include "ARMGenAsmMatcher.inc"
     578             : 
     579             :   };
     580             : 
     581        1317 :   ARMAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
     582             :                const MCInstrInfo &MII, const MCTargetOptions &Options)
     583        1317 :     : MCTargetAsmParser(Options, STI, MII), UC(Parser) {
     584        1317 :     MCAsmParserExtension::Initialize(Parser);
     585             : 
     586             :     // Cache the MCRegisterInfo.
     587        1317 :     MRI = getContext().getRegisterInfo();
     588             : 
     589             :     // Initialize the set of available features.
     590        1317 :     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
     591             : 
     592             :     // Add build attributes based on the selected target.
     593        1317 :     if (AddBuildAttributes)
     594          39 :       getTargetStreamer().emitTargetAttributes(STI);
     595             : 
     596             :     // Not in an ITBlock to start with.
     597        1317 :     ITState.CurPosition = ~0U;
     598             : 
     599        1317 :     NextSymbolIsThumb = false;
     600        1317 :   }
     601             : 
     602             :   // Implementation of the MCTargetAsmParser interface:
     603             :   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
     604             :   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
     605             :                         SMLoc NameLoc, OperandVector &Operands) override;
     606             :   bool ParseDirective(AsmToken DirectiveID) override;
     607             : 
     608             :   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
     609             :                                       unsigned Kind) override;
     610             :   unsigned checkTargetMatchPredicate(MCInst &Inst) override;
     611             : 
     612             :   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     613             :                                OperandVector &Operands, MCStreamer &Out,
     614             :                                uint64_t &ErrorInfo,
     615             :                                bool MatchingInlineAsm) override;
     616             :   unsigned MatchInstruction(OperandVector &Operands, MCInst &Inst,
     617             :                             SmallVectorImpl<NearMissInfo> &NearMisses,
     618             :                             bool MatchingInlineAsm, bool &EmitInITBlock,
     619             :                             MCStreamer &Out);
     620             : 
     621       11422 :   struct NearMissMessage {
     622             :     SMLoc Loc;
     623             :     SmallString<128> Message;
     624             :   };
     625             : 
     626             :   const char *getCustomOperandDiag(ARMMatchResultTy MatchError);
     627             : 
     628             :   void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
     629             :                         SmallVectorImpl<NearMissMessage> &NearMissesOut,
     630             :                         SMLoc IDLoc, OperandVector &Operands);
     631             :   void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
     632             :                         OperandVector &Operands);
     633             : 
     634             :   void doBeforeLabelEmit(MCSymbol *Symbol) override;
     635             : 
     636             :   void onLabelParsed(MCSymbol *Symbol) override;
     637             : };
     638             : 
     639             : /// ARMOperand - Instances of this class represent a parsed ARM machine
     640             : /// operand.
     641         906 : class ARMOperand : public MCParsedAsmOperand {
     642             :   enum KindTy {
     643             :     k_CondCode,
     644             :     k_CCOut,
     645             :     k_ITCondMask,
     646             :     k_CoprocNum,
     647             :     k_CoprocReg,
     648             :     k_CoprocOption,
     649             :     k_Immediate,
     650             :     k_MemBarrierOpt,
     651             :     k_InstSyncBarrierOpt,
     652             :     k_TraceSyncBarrierOpt,
     653             :     k_Memory,
     654             :     k_PostIndexRegister,
     655             :     k_MSRMask,
     656             :     k_BankedReg,
     657             :     k_ProcIFlags,
     658             :     k_VectorIndex,
     659             :     k_Register,
     660             :     k_RegisterList,
     661             :     k_DPRRegisterList,
     662             :     k_SPRRegisterList,
     663             :     k_VectorList,
     664             :     k_VectorListAllLanes,
     665             :     k_VectorListIndexed,
     666             :     k_ShiftedRegister,
     667             :     k_ShiftedImmediate,
     668             :     k_ShifterImmediate,
     669             :     k_RotateImmediate,
     670             :     k_ModifiedImmediate,
     671             :     k_ConstantPoolImmediate,
     672             :     k_BitfieldDescriptor,
     673             :     k_Token,
     674             :   } Kind;
     675             : 
     676             :   SMLoc StartLoc, EndLoc, AlignmentLoc;
     677             :   SmallVector<unsigned, 8> Registers;
     678             : 
     679             :   struct CCOp {
     680             :     ARMCC::CondCodes Val;
     681             :   };
     682             : 
     683             :   struct CopOp {
     684             :     unsigned Val;
     685             :   };
     686             : 
     687             :   struct CoprocOptionOp {
     688             :     unsigned Val;
     689             :   };
     690             : 
     691             :   struct ITMaskOp {
     692             :     unsigned Mask:4;
     693             :   };
     694             : 
     695             :   struct MBOptOp {
     696             :     ARM_MB::MemBOpt Val;
     697             :   };
     698             : 
     699             :   struct ISBOptOp {
     700             :     ARM_ISB::InstSyncBOpt Val;
     701             :   };
     702             : 
     703             :   struct TSBOptOp {
     704             :     ARM_TSB::TraceSyncBOpt Val;
     705             :   };
     706             : 
     707             :   struct IFlagsOp {
     708             :     ARM_PROC::IFlags Val;
     709             :   };
     710             : 
     711             :   struct MMaskOp {
     712             :     unsigned Val;
     713             :   };
     714             : 
     715             :   struct BankedRegOp {
     716             :     unsigned Val;
     717             :   };
     718             : 
     719             :   struct TokOp {
     720             :     const char *Data;
     721             :     unsigned Length;
     722             :   };
     723             : 
     724             :   struct RegOp {
     725             :     unsigned RegNum;
     726             :   };
     727             : 
     728             :   // A vector register list is a sequential list of 1 to 4 registers.
     729             :   struct VectorListOp {
     730             :     unsigned RegNum;
     731             :     unsigned Count;
     732             :     unsigned LaneIndex;
     733             :     bool isDoubleSpaced;
     734             :   };
     735             : 
     736             :   struct VectorIndexOp {
     737             :     unsigned Val;
     738             :   };
     739             : 
     740             :   struct ImmOp {
     741             :     const MCExpr *Val;
     742             :   };
     743             : 
     744             :   /// Combined record for all forms of ARM address expressions.
     745             :   struct MemoryOp {
     746             :     unsigned BaseRegNum;
     747             :     // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
     748             :     // was specified.
     749             :     const MCConstantExpr *OffsetImm;  // Offset immediate value
     750             :     unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
     751             :     ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
     752             :     unsigned ShiftImm;        // shift for OffsetReg.
     753             :     unsigned Alignment;       // 0 = no alignment specified
     754             :     // n = alignment in bytes (2, 4, 8, 16, or 32)
     755             :     unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
     756             :   };
     757             : 
     758             :   struct PostIdxRegOp {
     759             :     unsigned RegNum;
     760             :     bool isAdd;
     761             :     ARM_AM::ShiftOpc ShiftTy;
     762             :     unsigned ShiftImm;
     763             :   };
     764             : 
     765             :   struct ShifterImmOp {
     766             :     bool isASR;
     767             :     unsigned Imm;
     768             :   };
     769             : 
     770             :   struct RegShiftedRegOp {
     771             :     ARM_AM::ShiftOpc ShiftTy;
     772             :     unsigned SrcReg;
     773             :     unsigned ShiftReg;
     774             :     unsigned ShiftImm;
     775             :   };
     776             : 
     777             :   struct RegShiftedImmOp {
     778             :     ARM_AM::ShiftOpc ShiftTy;
     779             :     unsigned SrcReg;
     780             :     unsigned ShiftImm;
     781             :   };
     782             : 
     783             :   struct RotImmOp {
     784             :     unsigned Imm;
     785             :   };
     786             : 
     787             :   struct ModImmOp {
     788             :     unsigned Bits;
     789             :     unsigned Rot;
     790             :   };
     791             : 
     792             :   struct BitfieldOp {
     793             :     unsigned LSB;
     794             :     unsigned Width;
     795             :   };
     796             : 
     797             :   union {
     798             :     struct CCOp CC;
     799             :     struct CopOp Cop;
     800             :     struct CoprocOptionOp CoprocOption;
     801             :     struct MBOptOp MBOpt;
     802             :     struct ISBOptOp ISBOpt;
     803             :     struct TSBOptOp TSBOpt;
     804             :     struct ITMaskOp ITMask;
     805             :     struct IFlagsOp IFlags;
     806             :     struct MMaskOp MMask;
     807             :     struct BankedRegOp BankedReg;
     808             :     struct TokOp Tok;
     809             :     struct RegOp Reg;
     810             :     struct VectorListOp VectorList;
     811             :     struct VectorIndexOp VectorIndex;
     812             :     struct ImmOp Imm;
     813             :     struct MemoryOp Memory;
     814             :     struct PostIdxRegOp PostIdxReg;
     815             :     struct ShifterImmOp ShifterImm;
     816             :     struct RegShiftedRegOp RegShiftedReg;
     817             :     struct RegShiftedImmOp RegShiftedImm;
     818             :     struct RotImmOp RotImm;
     819             :     struct ModImmOp ModImm;
     820             :     struct BitfieldOp Bitfield;
     821             :   };
     822             : 
     823             : public:
     824           0 :   ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
     825             : 
     826             :   /// getStartLoc - Get the location of the first token of this operand.
     827         179 :   SMLoc getStartLoc() const override { return StartLoc; }
     828             : 
     829             :   /// getEndLoc - Get the location of the last token of this operand.
     830         109 :   SMLoc getEndLoc() const override { return EndLoc; }
     831             : 
     832             :   /// getLocRange - Get the range between the first and last token of this
     833             :   /// operand.
     834             :   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
     835             : 
     836             :   /// getAlignmentLoc - Get the location of the Alignment token of this operand.
     837             :   SMLoc getAlignmentLoc() const {
     838             :     assert(Kind == k_Memory && "Invalid access!");
     839             :     return AlignmentLoc;
     840             :   }
     841             : 
     842           0 :   ARMCC::CondCodes getCondCode() const {
     843             :     assert(Kind == k_CondCode && "Invalid access!");
     844           0 :     return CC.Val;
     845             :   }
     846             : 
     847           0 :   unsigned getCoproc() const {
     848             :     assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
     849           0 :     return Cop.Val;
     850             :   }
     851             : 
     852           0 :   StringRef getToken() const {
     853             :     assert(Kind == k_Token && "Invalid access!");
     854      259861 :     return StringRef(Tok.Data, Tok.Length);
     855             :   }
     856             : 
     857           0 :   unsigned getReg() const override {
     858             :     assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
     859      266847 :     return Reg.RegNum;
     860             :   }
     861             : 
     862             :   const SmallVectorImpl<unsigned> &getRegList() const {
     863             :     assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
     864             :             Kind == k_SPRRegisterList) && "Invalid access!");
     865          56 :     return Registers;
     866             :   }
     867             : 
     868           0 :   const MCExpr *getImm() const {
     869             :     assert(isImm() && "Invalid access!");
     870           0 :     return Imm.Val;
     871             :   }
     872             : 
     873           0 :   const MCExpr *getConstantPoolImm() const {
     874             :     assert(isConstantPoolImm() && "Invalid access!");
     875           0 :     return Imm.Val;
     876             :   }
     877             : 
     878           0 :   unsigned getVectorIndex() const {
     879             :     assert(Kind == k_VectorIndex && "Invalid access!");
     880           0 :     return VectorIndex.Val;
     881             :   }
     882             : 
     883           0 :   ARM_MB::MemBOpt getMemBarrierOpt() const {
     884             :     assert(Kind == k_MemBarrierOpt && "Invalid access!");
     885           0 :     return MBOpt.Val;
     886             :   }
     887             : 
     888           0 :   ARM_ISB::InstSyncBOpt getInstSyncBarrierOpt() const {
     889             :     assert(Kind == k_InstSyncBarrierOpt && "Invalid access!");
     890           0 :     return ISBOpt.Val;
     891             :   }
     892             : 
     893           0 :   ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
     894             :     assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!");
     895           0 :     return TSBOpt.Val;
     896             :   }
     897             : 
     898           0 :   ARM_PROC::IFlags getProcIFlags() const {
     899             :     assert(Kind == k_ProcIFlags && "Invalid access!");
     900           0 :     return IFlags.Val;
     901             :   }
     902             : 
     903           0 :   unsigned getMSRMask() const {
     904             :     assert(Kind == k_MSRMask && "Invalid access!");
     905           0 :     return MMask.Val;
     906             :   }
     907             : 
     908           0 :   unsigned getBankedReg() const {
     909             :     assert(Kind == k_BankedReg && "Invalid access!");
     910           0 :     return BankedReg.Val;
     911             :   }
     912             : 
     913           0 :   bool isCoprocNum() const { return Kind == k_CoprocNum; }
     914           0 :   bool isCoprocReg() const { return Kind == k_CoprocReg; }
     915           0 :   bool isCoprocOption() const { return Kind == k_CoprocOption; }
     916           0 :   bool isCondCode() const { return Kind == k_CondCode; }
     917           0 :   bool isCCOut() const { return Kind == k_CCOut; }
     918           0 :   bool isITMask() const { return Kind == k_ITCondMask; }
     919           0 :   bool isITCondCode() const { return Kind == k_CondCode; }
     920         486 :   bool isImm() const override {
     921       32034 :     return Kind == k_Immediate;
     922             :   }
     923             : 
     924             :   bool isARMBranchTarget() const {
     925        1029 :     if (!isImm()) return false;
     926             : 
     927         632 :     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
     928         158 :       return CE->getValue() % 4 == 0;
     929             :     return true;
     930             :   }
     931             : 
     932             : 
     933             :   bool isThumbBranchTarget() const {
     934         445 :     if (!isImm()) return false;
     935             : 
     936         262 :     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()))
     937          40 :       return CE->getValue() % 2 == 0;
     938             :     return true;
     939             :   }
     940             : 
     941             :   // checks whether this operand is an unsigned offset which fits is a field
     942             :   // of specified width and scaled by a specific number of bits
     943             :   template<unsigned width, unsigned scale>
     944             :   bool isUnsignedOffset() const {
     945         105 :     if (!isImm()) return false;
     946         196 :     if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
     947             :     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
     948          40 :       int64_t Val = CE->getValue();
     949             :       int64_t Align = 1LL << scale;
     950             :       int64_t Max = Align * ((1LL << width) - 1);
     951          40 :       return ((Val % Align) == 0) && (Val >= 0) && (Val <= Max);
     952             :     }
     953             :     return false;
     954             :   }
     955             : 
     956             :   // checks whether this operand is an signed offset which fits is a field
     957             :   // of specified width and scaled by a specific number of bits
     958             :   template<unsigned width, unsigned scale>
     959             :   bool isSignedOffset() const {
     960         629 :     if (!isImm()) return false;
     961        1258 :     if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
     962             :     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
     963         333 :       int64_t Val = CE->getValue();
     964             :       int64_t Align = 1LL << scale;
     965             :       int64_t Max = Align * ((1LL << (width-1)) - 1);
     966             :       int64_t Min = -Align * (1LL << (width-1));
     967         333 :       return ((Val % Align) == 0) && (Val >= Min) && (Val <= Max);
     968             :     }
     969             :     return false;
     970             :   }
     971             : 
     972             :   // checks whether this operand is a memory operand computed as an offset
     973             :   // applied to PC. the offset may have 8 bits of magnitude and is represented
     974             :   // with two bits of shift. textually it may be either [pc, #imm], #imm or
     975             :   // relocable expression...
     976         655 :   bool isThumbMemPC() const {
     977             :     int64_t Val = 0;
     978         655 :     if (isImm()) {
     979          96 :       if (isa<MCSymbolRefExpr>(Imm.Val)) return true;
     980             :       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val);
     981             :       if (!CE) return false;
     982           6 :       Val = CE->getValue();
     983             :     }
     984         607 :     else if (isMem()) {
     985         166 :       if(!Memory.OffsetImm || Memory.OffsetRegNum) return false;
     986          86 :       if(Memory.BaseRegNum != ARM::PC) return false;
     987          42 :       Val = Memory.OffsetImm->getValue();
     988             :     }
     989             :     else return false;
     990          48 :     return ((Val % 4) == 0) && (Val >= 0) && (Val <= 1020);
     991             :   }
     992             : 
     993         279 :   bool isFPImm() const {
     994         279 :     if (!isImm()) return false;
     995         187 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
     996             :     if (!CE) return false;
     997         187 :     int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
     998         187 :     return Val != -1;
     999             :   }
    1000             : 
    1001             :   template<int64_t N, int64_t M>
    1002             :   bool isImmediate() const {
    1003       11265 :     if (!isImm()) return false;
    1004        5413 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1005             :     if (!CE) return false;
    1006        5371 :     int64_t Value = CE->getValue();
    1007        5091 :     return Value >= N && Value <= M;
    1008             :   }
    1009             : 
    1010             :   template<int64_t N, int64_t M>
    1011             :   bool isImmediateS4() const {
    1012         352 :     if (!isImm()) return false;
    1013         174 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1014             :     if (!CE) return false;
    1015         174 :     int64_t Value = CE->getValue();
    1016         174 :     return ((Value & 3) == 0) && Value >= N && Value <= M;
    1017             :   }
    1018             : 
    1019             :   bool isFBits16() const {
    1020             :     return isImmediate<0, 17>();
    1021             :   }
    1022             :   bool isFBits32() const {
    1023             :     return isImmediate<1, 33>();
    1024             :   }
    1025             :   bool isImm8s4() const {
    1026             :     return isImmediateS4<-1020, 1020>();
    1027             :   }
    1028             :   bool isImm0_1020s4() const {
    1029             :     return isImmediateS4<0, 1020>();
    1030             :   }
    1031             :   bool isImm0_508s4() const {
    1032             :     return isImmediateS4<0, 508>();
    1033             :   }
    1034             :   bool isImm0_508s4Neg() const {
    1035         198 :     if (!isImm()) return false;
    1036          40 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1037             :     if (!CE) return false;
    1038          40 :     int64_t Value = -CE->getValue();
    1039             :     // explicitly exclude zero. we want that to use the normal 0_508 version.
    1040          40 :     return ((Value & 3) == 0) && Value > 0 && Value <= 508;
    1041             :   }
    1042             : 
    1043             :   bool isImm0_4095Neg() const {
    1044         225 :     if (!isImm()) return false;
    1045          23 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1046             :     if (!CE) return false;
    1047             :     // isImm0_4095Neg is used with 32-bit immediates only.
    1048             :     // 32-bit immediates are zero extended to 64-bit when parsed,
    1049             :     // thus simple -CE->getValue() results in a big negative number,
    1050             :     // not a small positive number as intended
    1051          23 :     if ((CE->getValue() >> 32) > 0) return false;
    1052          23 :     uint32_t Value = -static_cast<uint32_t>(CE->getValue());
    1053          23 :     return Value > 0 && Value < 4096;
    1054             :   }
    1055             : 
    1056             :   bool isImm0_7() const {
    1057             :     return isImmediate<0, 7>();
    1058             :   }
    1059             : 
    1060             :   bool isImm1_16() const {
    1061             :     return isImmediate<1, 16>();
    1062             :   }
    1063             : 
    1064             :   bool isImm1_32() const {
    1065             :     return isImmediate<1, 32>();
    1066             :   }
    1067             : 
    1068             :   bool isImm8_255() const {
    1069             :     return isImmediate<8, 255>();
    1070             :   }
    1071             : 
    1072             :   bool isImm256_65535Expr() const {
    1073             :     if (!isImm()) return false;
    1074             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1075             :     // If it's not a constant expression, it'll generate a fixup and be
    1076             :     // handled later.
    1077             :     if (!CE) return true;
    1078             :     int64_t Value = CE->getValue();
    1079             :     return Value >= 256 && Value < 65536;
    1080             :   }
    1081             : 
    1082             :   bool isImm0_65535Expr() const {
    1083         601 :     if (!isImm()) return false;
    1084         466 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1085             :     // If it's not a constant expression, it'll generate a fixup and be
    1086             :     // handled later.
    1087             :     if (!CE) return true;
    1088         145 :     int64_t Value = CE->getValue();
    1089         136 :     return Value >= 0 && Value < 65536;
    1090             :   }
    1091             : 
    1092             :   bool isImm24bit() const {
    1093             :     return isImmediate<0, 0xffffff + 1>();
    1094             :   }
    1095             : 
    1096             :   bool isImmThumbSR() const {
    1097             :     return isImmediate<1, 33>();
    1098             :   }
    1099             : 
    1100             :   bool isPKHLSLImm() const {
    1101             :     return isImmediate<0, 32>();
    1102             :   }
    1103             : 
    1104             :   bool isPKHASRImm() const {
    1105             :     return isImmediate<0, 33>();
    1106             :   }
    1107             : 
    1108          33 :   bool isAdrLabel() const {
    1109             :     // If we have an immediate that's not a constant, treat it as a label
    1110             :     // reference needing a fixup.
    1111          33 :     if (isImm() && !isa<MCConstantExpr>(getImm()))
    1112             :       return true;
    1113             : 
    1114             :     // If it is a constant, it must fit into a modified immediate encoding.
    1115          21 :     if (!isImm()) return false;
    1116          14 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1117             :     if (!CE) return false;
    1118          14 :     int64_t Value = CE->getValue();
    1119          14 :     return (ARM_AM::getSOImmVal(Value) != -1 ||
    1120           4 :             ARM_AM::getSOImmVal(-Value) != -1);
    1121             :   }
    1122             : 
    1123        6602 :   bool isT2SOImm() const {
    1124             :     // If we have an immediate that's not a constant, treat it as an expression
    1125             :     // needing a fixup.
    1126        6602 :     if (isImm() && !isa<MCConstantExpr>(getImm())) {
    1127             :       // We want to avoid matching :upper16: and :lower16: as we want these
    1128             :       // expressions to match in isImm0_65535Expr()
    1129             :       const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(getImm());
    1130           8 :       return (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 &&
    1131             :                              ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16));
    1132             :     }
    1133        6560 :     if (!isImm()) return false;
    1134        1344 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1135             :     if (!CE) return false;
    1136        1344 :     int64_t Value = CE->getValue();
    1137        1344 :     return ARM_AM::getT2SOImmVal(Value) != -1;
    1138             :   }
    1139             : 
    1140        2120 :   bool isT2SOImmNot() const {
    1141        2120 :     if (!isImm()) return false;
    1142         249 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1143             :     if (!CE) return false;
    1144         238 :     int64_t Value = CE->getValue();
    1145         238 :     return ARM_AM::getT2SOImmVal(Value) == -1 &&
    1146         107 :       ARM_AM::getT2SOImmVal(~Value) != -1;
    1147             :   }
    1148             : 
    1149        4802 :   bool isT2SOImmNeg() const {
    1150        4802 :     if (!isImm()) return false;
    1151         553 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1152             :     if (!CE) return false;
    1153         528 :     int64_t Value = CE->getValue();
    1154             :     // Only use this when not representable as a plain so_imm.
    1155         528 :     return ARM_AM::getT2SOImmVal(Value) == -1 &&
    1156          83 :       ARM_AM::getT2SOImmVal(-Value) != -1;
    1157             :   }
    1158             : 
    1159             :   bool isSetEndImm() const {
    1160             :     if (!isImm()) return false;
    1161             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1162             :     if (!CE) return false;
    1163             :     int64_t Value = CE->getValue();
    1164             :     return Value == 1 || Value == 0;
    1165             :   }
    1166             : 
    1167      471426 :   bool isReg() const override { return Kind == k_Register; }
    1168           0 :   bool isRegList() const { return Kind == k_RegisterList; }
    1169           0 :   bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
    1170           0 :   bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
    1171     1176357 :   bool isToken() const override { return Kind == k_Token; }
    1172           0 :   bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
    1173           0 :   bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
    1174           0 :   bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
    1175      114256 :   bool isMem() const override {
    1176      114256 :     if (Kind != k_Memory)
    1177             :       return false;
    1178      219302 :     if (Memory.BaseRegNum &&
    1179      109662 :         !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.BaseRegNum))
    1180             :       return false;
    1181      111352 :     if (Memory.OffsetRegNum &&
    1182        1782 :         !ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Memory.OffsetRegNum))
    1183          70 :       return false;
    1184             :     return true;
    1185             :   }
    1186           0 :   bool isShifterImm() const { return Kind == k_ShifterImmediate; }
    1187        4524 :   bool isRegShiftedReg() const {
    1188         247 :     return Kind == k_ShiftedRegister &&
    1189         247 :            ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
    1190        4770 :                RegShiftedReg.SrcReg) &&
    1191             :            ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
    1192         247 :                RegShiftedReg.ShiftReg);
    1193             :   }
    1194           0 :   bool isRegShiftedImm() const {
    1195       11787 :     return Kind == k_ShiftedImmediate &&
    1196        1069 :            ARMMCRegisterClasses[ARM::GPRRegClassID].contains(
    1197        1069 :                RegShiftedImm.SrcReg);
    1198             :   }
    1199           0 :   bool isRotImm() const { return Kind == k_RotateImmediate; }
    1200           0 :   bool isModImm() const { return Kind == k_ModifiedImmediate; }
    1201             : 
    1202        1552 :   bool isModImmNot() const {
    1203        1552 :     if (!isImm()) return false;
    1204          77 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1205             :     if (!CE) return false;
    1206          77 :     int64_t Value = CE->getValue();
    1207          77 :     return ARM_AM::getSOImmVal(~Value) != -1;
    1208             :   }
    1209             : 
    1210        1847 :   bool isModImmNeg() const {
    1211        1847 :     if (!isImm()) return false;
    1212          57 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1213             :     if (!CE) return false;
    1214          52 :     int64_t Value = CE->getValue();
    1215          52 :     return ARM_AM::getSOImmVal(Value) == -1 &&
    1216          39 :       ARM_AM::getSOImmVal(-Value) != -1;
    1217             :   }
    1218             : 
    1219             :   bool isThumbModImmNeg1_7() const {
    1220         802 :     if (!isImm()) return false;
    1221          83 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1222             :     if (!CE) return false;
    1223          71 :     int32_t Value = -(int32_t)CE->getValue();
    1224          71 :     return 0 < Value && Value < 8;
    1225             :   }
    1226             : 
    1227             :   bool isThumbModImmNeg8_255() const {
    1228        1504 :     if (!isImm()) return false;
    1229          53 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1230             :     if (!CE) return false;
    1231          53 :     int32_t Value = -(int32_t)CE->getValue();
    1232          53 :     return 7 < Value && Value < 256;
    1233             :   }
    1234             : 
    1235           0 :   bool isConstantPoolImm() const { return Kind == k_ConstantPoolImmediate; }
    1236           0 :   bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
    1237           0 :   bool isPostIdxRegShifted() const {
    1238         141 :     return Kind == k_PostIndexRegister &&
    1239          76 :            ARMMCRegisterClasses[ARM::GPRRegClassID].contains(PostIdxReg.RegNum);
    1240             :   }
    1241         108 :   bool isPostIdxReg() const {
    1242         143 :     return isPostIdxRegShifted() && PostIdxReg.ShiftTy == ARM_AM::no_shift;
    1243             :   }
    1244      101136 :   bool isMemNoOffset(bool alignOK = false, unsigned Alignment = 0) const {
    1245      101136 :     if (!isMem())
    1246             :       return false;
    1247             :     // No offset of any kind.
    1248      101005 :     return Memory.OffsetRegNum == 0 && Memory.OffsetImm == nullptr &&
    1249      100784 :      (alignOK || Memory.Alignment == Alignment);
    1250             :   }
    1251         506 :   bool isMemPCRelImm12() const {
    1252         506 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1253             :       return false;
    1254             :     // Base register must be PC.
    1255         221 :     if (Memory.BaseRegNum != ARM::PC)
    1256             :       return false;
    1257             :     // Immediate offset in range [-4095, 4095].
    1258          69 :     if (!Memory.OffsetImm) return true;
    1259          69 :     int64_t Val = Memory.OffsetImm->getValue();
    1260          69 :     return (Val > -4096 && Val < 4096) ||
    1261             :            (Val == std::numeric_limits<int32_t>::min());
    1262             :   }
    1263             : 
    1264             :   bool isAlignedMemory() const {
    1265           0 :     return isMemNoOffset(true);
    1266             :   }
    1267             : 
    1268             :   bool isAlignedMemoryNone() const {
    1269        4099 :     return isMemNoOffset(false, 0);
    1270             :   }
    1271             : 
    1272             :   bool isDupAlignedMemoryNone() const {
    1273        3476 :     return isMemNoOffset(false, 0);
    1274             :   }
    1275             : 
    1276        1262 :   bool isAlignedMemory16() const {
    1277        1262 :     if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
    1278             :       return true;
    1279        1026 :     return isMemNoOffset(false, 0);
    1280             :   }
    1281             : 
    1282        1686 :   bool isDupAlignedMemory16() const {
    1283        1686 :     if (isMemNoOffset(false, 2)) // alignment in bytes for 16-bits is 2.
    1284             :       return true;
    1285        1410 :     return isMemNoOffset(false, 0);
    1286             :   }
    1287             : 
    1288        1994 :   bool isAlignedMemory32() const {
    1289        1994 :     if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
    1290             :       return true;
    1291        1640 :     return isMemNoOffset(false, 0);
    1292             :   }
    1293             : 
    1294        2558 :   bool isDupAlignedMemory32() const {
    1295        2558 :     if (isMemNoOffset(false, 4)) // alignment in bytes for 32-bits is 4.
    1296             :       return true;
    1297        2143 :     return isMemNoOffset(false, 0);
    1298             :   }
    1299             : 
    1300       12694 :   bool isAlignedMemory64() const {
    1301       12694 :     if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
    1302             :       return true;
    1303       11032 :     return isMemNoOffset(false, 0);
    1304             :   }
    1305             : 
    1306        1743 :   bool isDupAlignedMemory64() const {
    1307        1743 :     if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
    1308             :       return true;
    1309        1506 :     return isMemNoOffset(false, 0);
    1310             :   }
    1311             : 
    1312        8472 :   bool isAlignedMemory64or128() const {
    1313        8472 :     if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
    1314             :       return true;
    1315        7217 :     if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
    1316             :       return true;
    1317        5985 :     return isMemNoOffset(false, 0);
    1318             :   }
    1319             : 
    1320         793 :   bool isDupAlignedMemory64or128() const {
    1321         793 :     if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
    1322             :       return true;
    1323         696 :     if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
    1324             :       return true;
    1325         588 :     return isMemNoOffset(false, 0);
    1326             :   }
    1327             : 
    1328        8721 :   bool isAlignedMemory64or128or256() const {
    1329        8721 :     if (isMemNoOffset(false, 8)) // alignment in bytes for 64-bits is 8.
    1330             :       return true;
    1331        7457 :     if (isMemNoOffset(false, 16)) // alignment in bytes for 128-bits is 16.
    1332             :       return true;
    1333        6239 :     if (isMemNoOffset(false, 32)) // alignment in bytes for 256-bits is 32.
    1334             :       return true;
    1335        4757 :     return isMemNoOffset(false, 0);
    1336             :   }
    1337             : 
    1338             :   bool isAddrMode2() const {
    1339             :     if (!isMem() || Memory.Alignment != 0) return false;
    1340             :     // Check for register offset.
    1341             :     if (Memory.OffsetRegNum) return true;
    1342             :     // Immediate offset in range [-4095, 4095].
    1343             :     if (!Memory.OffsetImm) return true;
    1344             :     int64_t Val = Memory.OffsetImm->getValue();
    1345             :     return Val > -4096 && Val < 4096;
    1346             :   }
    1347             : 
    1348             :   bool isAM2OffsetImm() const {
    1349         106 :     if (!isImm()) return false;
    1350             :     // Immediate offset in range [-4095, 4095].
    1351          43 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1352             :     if (!CE) return false;
    1353          43 :     int64_t Val = CE->getValue();
    1354          43 :     return (Val == std::numeric_limits<int32_t>::min()) ||
    1355          41 :            (Val > -4096 && Val < 4096);
    1356             :   }
    1357             : 
    1358         711 :   bool isAddrMode3() const {
    1359             :     // If we have an immediate that's not a constant, treat it as a label
    1360             :     // reference needing a fixup. If it is a constant, it's something else
    1361             :     // and we reject it.
    1362         711 :     if (isImm() && !isa<MCConstantExpr>(getImm()))
    1363             :       return true;
    1364         709 :     if (!isMem() || Memory.Alignment != 0) return false;
    1365             :     // No shifts are legal for AM3.
    1366         527 :     if (Memory.ShiftType != ARM_AM::no_shift) return false;
    1367             :     // Check for register offset.
    1368         527 :     if (Memory.OffsetRegNum) return true;
    1369             :     // Immediate offset in range [-255, 255].
    1370         467 :     if (!Memory.OffsetImm) return true;
    1371         206 :     int64_t Val = Memory.OffsetImm->getValue();
    1372             :     // The #-0 offset is encoded as std::numeric_limits<int32_t>::min(), and we
    1373             :     // have to check for this too.
    1374         206 :     return (Val > -256 && Val < 256) ||
    1375             :            Val == std::numeric_limits<int32_t>::min();
    1376             :   }
    1377             : 
    1378          83 :   bool isAM3Offset() const {
    1379          83 :     if (isPostIdxReg())
    1380             :       return true;
    1381          60 :     if (!isImm())
    1382             :       return false;
    1383             :     // Immediate offset in range [-255, 255].
    1384          56 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1385             :     if (!CE) return false;
    1386          56 :     int64_t Val = CE->getValue();
    1387             :     // Special case, #-0 is std::numeric_limits<int32_t>::min().
    1388          56 :     return (Val > -256 && Val < 256) ||
    1389             :            Val == std::numeric_limits<int32_t>::min();
    1390             :   }
    1391             : 
    1392        2250 :   bool isAddrMode5() const {
    1393             :     // If we have an immediate that's not a constant, treat it as a label
    1394             :     // reference needing a fixup. If it is a constant, it's something else
    1395             :     // and we reject it.
    1396        2250 :     if (isImm() && !isa<MCConstantExpr>(getImm()))
    1397             :       return true;
    1398        2249 :     if (!isMem() || Memory.Alignment != 0) return false;
    1399             :     // Check for register offset.
    1400        2141 :     if (Memory.OffsetRegNum) return false;
    1401             :     // Immediate offset in range [-1020, 1020] and a multiple of 4.
    1402        2141 :     if (!Memory.OffsetImm) return true;
    1403         890 :     int64_t Val = Memory.OffsetImm->getValue();
    1404         890 :     return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
    1405             :       Val == std::numeric_limits<int32_t>::min();
    1406             :   }
    1407             : 
    1408          43 :   bool isAddrMode5FP16() const {
    1409             :     // If we have an immediate that's not a constant, treat it as a label
    1410             :     // reference needing a fixup. If it is a constant, it's something else
    1411             :     // and we reject it.
    1412          43 :     if (isImm() && !isa<MCConstantExpr>(getImm()))
    1413             :       return true;
    1414          43 :     if (!isMem() || Memory.Alignment != 0) return false;
    1415             :     // Check for register offset.
    1416          43 :     if (Memory.OffsetRegNum) return false;
    1417             :     // Immediate offset in range [-510, 510] and a multiple of 2.
    1418          43 :     if (!Memory.OffsetImm) return true;
    1419          38 :     int64_t Val = Memory.OffsetImm->getValue();
    1420          38 :     return (Val >= -510 && Val <= 510 && ((Val & 1) == 0)) ||
    1421             :            Val == std::numeric_limits<int32_t>::min();
    1422             :   }
    1423             : 
    1424           7 :   bool isMemTBB() const {
    1425           7 :     if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative ||
    1426          14 :         Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
    1427           0 :       return false;
    1428             :     return true;
    1429             :   }
    1430             : 
    1431           7 :   bool isMemTBH() const {
    1432           7 :     if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative ||
    1433          14 :         Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
    1434             :         Memory.Alignment != 0 )
    1435           0 :       return false;
    1436             :     return true;
    1437             :   }
    1438             : 
    1439             :   bool isMemRegOffset() const {
    1440         773 :     if (!isMem() || !Memory.OffsetRegNum || Memory.Alignment != 0)
    1441             :       return false;
    1442             :     return true;
    1443             :   }
    1444             : 
    1445        1023 :   bool isT2MemRegOffset() const {
    1446         668 :     if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative ||
    1447        1317 :         Memory.Alignment != 0 || Memory.BaseRegNum == ARM::PC)
    1448             :       return false;
    1449             :     // Only lsl #{0, 1, 2, 3} allowed.
    1450         284 :     if (Memory.ShiftType == ARM_AM::no_shift)
    1451             :       return true;
    1452          84 :     if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
    1453           3 :       return false;
    1454             :     return true;
    1455             :   }
    1456             : 
    1457        1195 :   bool isMemThumbRR() const {
    1458             :     // Thumb reg+reg addressing is simple. Just two registers, a base and
    1459             :     // an offset. No shifts, negations or any other complicating factors.
    1460         659 :     if (!isMem() || !Memory.OffsetRegNum || Memory.isNegative ||
    1461        1383 :         Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
    1462             :       return false;
    1463         104 :     return isARMLowRegister(Memory.BaseRegNum) &&
    1464             :       (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
    1465             :   }
    1466             : 
    1467         575 :   bool isMemThumbRIs4() const {
    1468         289 :     if (!isMem() || Memory.OffsetRegNum != 0 ||
    1469         791 :         !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
    1470             :       return false;
    1471             :     // Immediate offset, multiple of 4 in range [0, 124].
    1472         125 :     if (!Memory.OffsetImm) return true;
    1473          75 :     int64_t Val = Memory.OffsetImm->getValue();
    1474          75 :     return Val >= 0 && Val <= 124 && (Val % 4) == 0;
    1475             :   }
    1476             : 
    1477         237 :   bool isMemThumbRIs2() const {
    1478         157 :     if (!isMem() || Memory.OffsetRegNum != 0 ||
    1479         350 :         !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
    1480             :       return false;
    1481             :     // Immediate offset, multiple of 4 in range [0, 62].
    1482          91 :     if (!Memory.OffsetImm) return true;
    1483          57 :     int64_t Val = Memory.OffsetImm->getValue();
    1484          57 :     return Val >= 0 && Val <= 62 && (Val % 2) == 0;
    1485             :   }
    1486             : 
    1487         243 :   bool isMemThumbRIs1() const {
    1488         165 :     if (!isMem() || Memory.OffsetRegNum != 0 ||
    1489         361 :         !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
    1490             :       return false;
    1491             :     // Immediate offset in range [0, 31].
    1492          96 :     if (!Memory.OffsetImm) return true;
    1493          56 :     int64_t Val = Memory.OffsetImm->getValue();
    1494          56 :     return Val >= 0 && Val <= 31;
    1495             :   }
    1496             : 
    1497         534 :   bool isMemThumbSPI() const {
    1498         248 :     if (!isMem() || Memory.OffsetRegNum != 0 ||
    1499         718 :         Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
    1500             :       return false;
    1501             :     // Immediate offset, multiple of 4 in range [0, 1020].
    1502          50 :     if (!Memory.OffsetImm) return true;
    1503          29 :     int64_t Val = Memory.OffsetImm->getValue();
    1504          29 :     return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
    1505             :   }
    1506             : 
    1507         421 :   bool isMemImm8s4Offset() const {
    1508             :     // If we have an immediate that's not a constant, treat it as a label
    1509             :     // reference needing a fixup. If it is a constant, it's something else
    1510             :     // and we reject it.
    1511         421 :     if (isImm() && !isa<MCConstantExpr>(getImm()))
    1512             :       return true;
    1513         419 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1514             :       return false;
    1515             :     // Immediate offset a multiple of 4 in range [-1020, 1020].
    1516         399 :     if (!Memory.OffsetImm) return true;
    1517         174 :     int64_t Val = Memory.OffsetImm->getValue();
    1518             :     // Special case, #-0 is std::numeric_limits<int32_t>::min().
    1519         174 :     return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) ||
    1520             :            Val == std::numeric_limits<int32_t>::min();
    1521             :   }
    1522             : 
    1523          44 :   bool isMemImm0_1020s4Offset() const {
    1524          44 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1525             :       return false;
    1526             :     // Immediate offset a multiple of 4 in range [0, 1020].
    1527          44 :     if (!Memory.OffsetImm) return true;
    1528          14 :     int64_t Val = Memory.OffsetImm->getValue();
    1529          14 :     return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
    1530             :   }
    1531             : 
    1532         356 :   bool isMemImm8Offset() const {
    1533         356 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1534             :       return false;
    1535             :     // Base reg of PC isn't allowed for these encodings.
    1536         289 :     if (Memory.BaseRegNum == ARM::PC) return false;
    1537             :     // Immediate offset in range [-255, 255].
    1538         279 :     if (!Memory.OffsetImm) return true;
    1539         116 :     int64_t Val = Memory.OffsetImm->getValue();
    1540         116 :     return (Val == std::numeric_limits<int32_t>::min()) ||
    1541         112 :            (Val > -256 && Val < 256);
    1542             :   }
    1543             : 
    1544          74 :   bool isMemPosImm8Offset() const {
    1545          74 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1546             :       return false;
    1547             :     // Immediate offset in range [0, 255].
    1548          74 :     if (!Memory.OffsetImm) return true;
    1549          30 :     int64_t Val = Memory.OffsetImm->getValue();
    1550          30 :     return Val >= 0 && Val < 256;
    1551             :   }
    1552             : 
    1553        1078 :   bool isMemNegImm8Offset() const {
    1554        1078 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1555             :       return false;
    1556             :     // Base reg of PC isn't allowed for these encodings.
    1557         417 :     if (Memory.BaseRegNum == ARM::PC) return false;
    1558             :     // Immediate offset in range [-255, -1].
    1559         357 :     if (!Memory.OffsetImm) return false;
    1560         207 :     int64_t Val = Memory.OffsetImm->getValue();
    1561         207 :     return (Val == std::numeric_limits<int32_t>::min()) ||
    1562         198 :            (Val > -256 && Val < 0);
    1563             :   }
    1564             : 
    1565        1273 :   bool isMemUImm12Offset() const {
    1566        1273 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1567             :       return false;
    1568             :     // Immediate offset in range [0, 4095].
    1569         612 :     if (!Memory.OffsetImm) return true;
    1570         341 :     int64_t Val = Memory.OffsetImm->getValue();
    1571         341 :     return (Val >= 0 && Val < 4096);
    1572             :   }
    1573             : 
    1574         913 :   bool isMemImm12Offset() const {
    1575             :     // If we have an immediate that's not a constant, treat it as a label
    1576             :     // reference needing a fixup. If it is a constant, it's something else
    1577             :     // and we reject it.
    1578             : 
    1579         913 :     if (isImm() && !isa<MCConstantExpr>(getImm()))
    1580             :       return true;
    1581             : 
    1582         899 :     if (!isMem() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
    1583             :       return false;
    1584             :     // Immediate offset in range [-4095, 4095].
    1585         351 :     if (!Memory.OffsetImm) return true;
    1586         190 :     int64_t Val = Memory.OffsetImm->getValue();
    1587         190 :     return (Val > -4096 && Val < 4096) ||
    1588             :            (Val == std::numeric_limits<int32_t>::min());
    1589             :   }
    1590             : 
    1591             :   bool isConstPoolAsmImm() const {
    1592             :     // Delay processing of Constant Pool Immediate, this will turn into
    1593             :     // a constant. Match no other operand
    1594             :     return (isConstantPoolImm());
    1595             :   }
    1596             : 
    1597             :   bool isPostIdxImm8() const {
    1598          19 :     if (!isImm()) return false;
    1599          16 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1600             :     if (!CE) return false;
    1601          16 :     int64_t Val = CE->getValue();
    1602          16 :     return (Val > -256 && Val < 256) ||
    1603             :            (Val == std::numeric_limits<int32_t>::min());
    1604             :   }
    1605             : 
    1606             :   bool isPostIdxImm8s4() const {
    1607         352 :     if (!isImm()) return false;
    1608         352 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1609             :     if (!CE) return false;
    1610         352 :     int64_t Val = CE->getValue();
    1611         352 :     return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
    1612             :            (Val == std::numeric_limits<int32_t>::min());
    1613             :   }
    1614             : 
    1615           0 :   bool isMSRMask() const { return Kind == k_MSRMask; }
    1616           0 :   bool isBankedReg() const { return Kind == k_BankedReg; }
    1617           0 :   bool isProcIFlags() const { return Kind == k_ProcIFlags; }
    1618             : 
    1619             :   // NEON operands.
    1620           0 :   bool isSingleSpacedVectorList() const {
    1621       52089 :     return Kind == k_VectorList && !VectorList.isDoubleSpaced;
    1622             :   }
    1623             : 
    1624           0 :   bool isDoubleSpacedVectorList() const {
    1625        8316 :     return Kind == k_VectorList && VectorList.isDoubleSpaced;
    1626             :   }
    1627             : 
    1628             :   bool isVecListOneD() const {
    1629             :     if (!isSingleSpacedVectorList()) return false;
    1630        5711 :     return VectorList.Count == 1;
    1631             :   }
    1632             : 
    1633             :   bool isVecListDPair() const {
    1634             :     if (!isSingleSpacedVectorList()) return false;
    1635             :     return (ARMMCRegisterClasses[ARM::DPairRegClassID]
    1636        7494 :               .contains(VectorList.RegNum));
    1637             :   }
    1638             : 
    1639             :   bool isVecListThreeD() const {
    1640             :     if (!isSingleSpacedVectorList()) return false;
    1641        6518 :     return VectorList.Count == 3;
    1642             :   }
    1643             : 
    1644             :   bool isVecListFourD() const {
    1645             :     if (!isSingleSpacedVectorList()) return false;
    1646        7988 :     return VectorList.Count == 4;
    1647             :   }
    1648             : 
    1649             :   bool isVecListDPairSpaced() const {
    1650        4028 :     if (Kind != k_VectorList) return false;
    1651             :     if (isSingleSpacedVectorList()) return false;
    1652             :     return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
    1653         651 :               .contains(VectorList.RegNum));
    1654             :   }
    1655             : 
    1656             :   bool isVecListThreeQ() const {
    1657             :     if (!isDoubleSpacedVectorList()) return false;
    1658         990 :     return VectorList.Count == 3;
    1659             :   }
    1660             : 
    1661             :   bool isVecListFourQ() const {
    1662             :     if (!isDoubleSpacedVectorList()) return false;
    1663         846 :     return VectorList.Count == 4;
    1664             :   }
    1665             : 
    1666           0 :   bool isSingleSpacedVectorAllLanes() const {
    1667       15831 :     return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
    1668             :   }
    1669             : 
    1670           0 :   bool isDoubleSpacedVectorAllLanes() const {
    1671        7771 :     return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
    1672             :   }
    1673             : 
    1674             :   bool isVecListOneDAllLanes() const {
    1675             :     if (!isSingleSpacedVectorAllLanes()) return false;
    1676         858 :     return VectorList.Count == 1;
    1677             :   }
    1678             : 
    1679             :   bool isVecListDPairAllLanes() const {
    1680             :     if (!isSingleSpacedVectorAllLanes()) return false;
    1681             :     return (ARMMCRegisterClasses[ARM::DPairRegClassID]
    1682        1317 :               .contains(VectorList.RegNum));
    1683             :   }
    1684             : 
    1685             :   bool isVecListDPairSpacedAllLanes() const {
    1686             :     if (!isDoubleSpacedVectorAllLanes()) return false;
    1687         429 :     return VectorList.Count == 2;
    1688             :   }
    1689             : 
    1690             :   bool isVecListThreeDAllLanes() const {
    1691             :     if (!isSingleSpacedVectorAllLanes()) return false;
    1692         495 :     return VectorList.Count == 3;
    1693             :   }
    1694             : 
    1695             :   bool isVecListThreeQAllLanes() const {
    1696             :     if (!isDoubleSpacedVectorAllLanes()) return false;
    1697         495 :     return VectorList.Count == 3;
    1698             :   }
    1699             : 
    1700             :   bool isVecListFourDAllLanes() const {
    1701             :     if (!isSingleSpacedVectorAllLanes()) return false;
    1702         447 :     return VectorList.Count == 4;
    1703             :   }
    1704             : 
    1705             :   bool isVecListFourQAllLanes() const {
    1706             :     if (!isDoubleSpacedVectorAllLanes()) return false;
    1707         447 :     return VectorList.Count == 4;
    1708             :   }
    1709             : 
    1710           0 :   bool isSingleSpacedVectorIndexed() const {
    1711       18580 :     return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
    1712             :   }
    1713             : 
    1714           0 :   bool isDoubleSpacedVectorIndexed() const {
    1715        8444 :     return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
    1716             :   }
    1717             : 
    1718             :   bool isVecListOneDByteIndexed() const {
    1719             :     if (!isSingleSpacedVectorIndexed()) return false;
    1720         313 :     return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
    1721             :   }
    1722             : 
    1723             :   bool isVecListOneDHWordIndexed() const {
    1724             :     if (!isSingleSpacedVectorIndexed()) return false;
    1725         374 :     return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
    1726             :   }
    1727             : 
    1728             :   bool isVecListOneDWordIndexed() const {
    1729             :     if (!isSingleSpacedVectorIndexed()) return false;
    1730         346 :     return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
    1731             :   }
    1732             : 
    1733             :   bool isVecListTwoDByteIndexed() const {
    1734             :     if (!isSingleSpacedVectorIndexed()) return false;
    1735         232 :     return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
    1736             :   }
    1737             : 
    1738             :   bool isVecListTwoDHWordIndexed() const {
    1739             :     if (!isSingleSpacedVectorIndexed()) return false;
    1740         274 :     return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
    1741             :   }
    1742             : 
    1743             :   bool isVecListTwoQWordIndexed() const {
    1744             :     if (!isDoubleSpacedVectorIndexed()) return false;
    1745         150 :     return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
    1746             :   }
    1747             : 
    1748             :   bool isVecListTwoQHWordIndexed() const {
    1749             :     if (!isDoubleSpacedVectorIndexed()) return false;
    1750         172 :     return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
    1751             :   }
    1752             : 
    1753             :   bool isVecListTwoDWordIndexed() const {
    1754             :     if (!isSingleSpacedVectorIndexed()) return false;
    1755         258 :     return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
    1756             :   }
    1757             : 
    1758             :   bool isVecListThreeDByteIndexed() const {
    1759             :     if (!isSingleSpacedVectorIndexed()) return false;
    1760         312 :     return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
    1761             :   }
    1762             : 
    1763             :   bool isVecListThreeDHWordIndexed() const {
    1764             :     if (!isSingleSpacedVectorIndexed()) return false;
    1765         356 :     return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
    1766             :   }
    1767             : 
    1768             :   bool isVecListThreeQWordIndexed() const {
    1769             :     if (!isDoubleSpacedVectorIndexed()) return false;
    1770         214 :     return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
    1771             :   }
    1772             : 
    1773             :   bool isVecListThreeQHWordIndexed() const {
    1774             :     if (!isDoubleSpacedVectorIndexed()) return false;
    1775         236 :     return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
    1776             :   }
    1777             : 
    1778             :   bool isVecListThreeDWordIndexed() const {
    1779             :     if (!isSingleSpacedVectorIndexed()) return false;
    1780         334 :     return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
    1781             :   }
    1782             : 
    1783             :   bool isVecListFourDByteIndexed() const {
    1784             :     if (!isSingleSpacedVectorIndexed()) return false;
    1785         288 :     return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
    1786             :   }
    1787             : 
    1788             :   bool isVecListFourDHWordIndexed() const {
    1789             :     if (!isSingleSpacedVectorIndexed()) return false;
    1790         374 :     return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
    1791             :   }
    1792             : 
    1793             :   bool isVecListFourQWordIndexed() const {
    1794             :     if (!isDoubleSpacedVectorIndexed()) return false;
    1795         233 :     return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
    1796             :   }
    1797             : 
    1798             :   bool isVecListFourQHWordIndexed() const {
    1799             :     if (!isDoubleSpacedVectorIndexed()) return false;
    1800         270 :     return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
    1801             :   }
    1802             : 
    1803             :   bool isVecListFourDWordIndexed() const {
    1804             :     if (!isSingleSpacedVectorIndexed()) return false;
    1805         337 :     return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
    1806             :   }
    1807             : 
    1808           0 :   bool isVectorIndex8() const {
    1809          66 :     if (Kind != k_VectorIndex) return false;
    1810          59 :     return VectorIndex.Val < 8;
    1811             :   }
    1812             : 
    1813           0 :   bool isVectorIndex16() const {
    1814         377 :     if (Kind != k_VectorIndex) return false;
    1815         292 :     return VectorIndex.Val < 4;
    1816             :   }
    1817             : 
    1818           0 :   bool isVectorIndex32() const {
    1819         527 :     if (Kind != k_VectorIndex) return false;
    1820         408 :     return VectorIndex.Val < 2;
    1821             :   }
    1822           0 :   bool isVectorIndex64() const {
    1823         154 :     if (Kind != k_VectorIndex) return false;
    1824         104 :     return VectorIndex.Val < 1;
    1825             :   }
    1826             : 
    1827             :   bool isNEONi8splat() const {
    1828          60 :     if (!isImm()) return false;
    1829          13 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1830             :     // Must be a constant.
    1831             :     if (!CE) return false;
    1832          13 :     int64_t Value = CE->getValue();
    1833             :     // i8 value splatted across 8 bytes. The immediate is just the 8 byte
    1834             :     // value.
    1835          13 :     return Value >= 0 && Value < 256;
    1836             :   }
    1837             : 
    1838         272 :   bool isNEONi16splat() const {
    1839         165 :     if (isNEONByteReplicate(2))
    1840             :       return false; // Leave that for bytes replication and forbid by default.
    1841         199 :     if (!isImm())
    1842             :       return false;
    1843          93 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1844             :     // Must be a constant.
    1845             :     if (!CE) return false;
    1846          93 :     unsigned Value = CE->getValue();
    1847             :     return ARM_AM::isNEONi16splat(Value);
    1848             :   }
    1849             : 
    1850          50 :   bool isNEONi16splatNot() const {
    1851          50 :     if (!isImm())
    1852             :       return false;
    1853          14 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1854             :     // Must be a constant.
    1855             :     if (!CE) return false;
    1856          14 :     unsigned Value = CE->getValue();
    1857          14 :     return ARM_AM::isNEONi16splat(~Value & 0xffff);
    1858             :   }
    1859             : 
    1860          81 :   bool isNEONi32splat() const {
    1861          46 :     if (isNEONByteReplicate(4))
    1862             :       return false; // Leave that for bytes replication and forbid by default.
    1863          65 :     if (!isImm())
    1864             :       return false;
    1865          31 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1866             :     // Must be a constant.
    1867             :     if (!CE) return false;
    1868          31 :     unsigned Value = CE->getValue();
    1869             :     return ARM_AM::isNEONi32splat(Value);
    1870             :   }
    1871             : 
    1872          48 :   bool isNEONi32splatNot() const {
    1873          48 :     if (!isImm())
    1874             :       return false;
    1875          12 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1876             :     // Must be a constant.
    1877             :     if (!CE) return false;
    1878          12 :     unsigned Value = CE->getValue();
    1879          12 :     return ARM_AM::isNEONi32splat(~Value);
    1880             :   }
    1881             : 
    1882             :   static bool isValidNEONi32vmovImm(int64_t Value) {
    1883             :     // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
    1884             :     // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
    1885         608 :     return ((Value & 0xffffffffffffff00) == 0) ||
    1886         282 :            ((Value & 0xffffffffffff00ff) == 0) ||
    1887         264 :            ((Value & 0xffffffffff00ffff) == 0) ||
    1888         250 :            ((Value & 0xffffffff00ffffff) == 0) ||
    1889         236 :            ((Value & 0xffffffffffff00ff) == 0xff) ||
    1890             :            ((Value & 0xffffffffff00ffff) == 0xffff);
    1891             :   }
    1892             : 
    1893         366 :   bool isNEONReplicate(unsigned Width, unsigned NumElems, bool Inv) const {
    1894             :     assert((Width == 8 || Width == 16 || Width == 32) &&
    1895             :            "Invalid element width");
    1896             :     assert(NumElems * Width <= 64 && "Invalid result width");
    1897             : 
    1898        1091 :     if (!isImm())
    1899             :       return false;
    1900         961 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1901             :     // Must be a constant.
    1902             :     if (!CE)
    1903             :       return false;
    1904         961 :     int64_t Value = CE->getValue();
    1905         961 :     if (!Value)
    1906             :       return false; // Don't bother with zero.
    1907         206 :     if (Inv)
    1908           0 :       Value = ~Value;
    1909             : 
    1910         206 :     uint64_t Mask = (1ull << Width) - 1;
    1911         624 :     uint64_t Elem = Value & Mask;
    1912         206 :     if (Width == 16 && (Elem & 0x00ff) != 0 && (Elem & 0xff00) != 0)
    1913             :       return false;
    1914         138 :     if (Width == 32 && !isValidNEONi32vmovImm(Elem))
    1915             :       return false;
    1916             : 
    1917        1362 :     for (unsigned i = 1; i < NumElems; ++i) {
    1918        1301 :       Value >>= Width;
    1919        1301 :       if ((Value & Mask) != Elem)
    1920             :         return false;
    1921             :     }
    1922             :     return true;
    1923             :   }
    1924             : 
    1925             :   bool isNEONByteReplicate(unsigned NumBytes) const {
    1926             :     return isNEONReplicate(8, NumBytes, false);
    1927             :   }
    1928             : 
    1929           0 :   static void checkNeonReplicateArgs(unsigned FromW, unsigned ToW) {
    1930             :     assert((FromW == 8 || FromW == 16 || FromW == 32) &&
    1931             :            "Invalid source width");
    1932             :     assert((ToW == 16 || ToW == 32 || ToW == 64) &&
    1933             :            "Invalid destination width");
    1934             :     assert(FromW < ToW && "ToW is not less than FromW");
    1935           0 :   }
    1936             : 
    1937             :   template<unsigned FromW, unsigned ToW>
    1938         278 :   bool isNEONmovReplicate() const {
    1939             :     checkNeonReplicateArgs(FromW, ToW);
    1940         143 :     if (ToW == 64 && isNEONi64splat())
    1941             :       return false;
    1942         366 :     return isNEONReplicate(FromW, ToW / FromW, false);
    1943             :   }
    1944         100 : 
    1945             :   template<unsigned FromW, unsigned ToW>
    1946          48 :   bool isNEONinvReplicate() const {
    1947             :     checkNeonReplicateArgs(FromW, ToW);
    1948          87 :     return isNEONReplicate(FromW, ToW / FromW, true);
    1949             :   }
    1950         108 : 
    1951             :   bool isNEONi32vmov() const {
    1952          56 :     if (isNEONByteReplicate(4))
    1953             :       return false; // Let it to be classified as byte-replicate case.
    1954          95 :     if (!isImm())
    1955             :       return false;
    1956          70 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1957             :     // Must be a constant.
    1958          39 :     if (!CE)
    1959             :       return false;
    1960             :     return isValidNEONi32vmovImm(CE->getValue());
    1961             :   }
    1962             : 
    1963             :   bool isNEONi32vmovNeg() const {
    1964         121 :     if (!isImm()) return false;
    1965             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1966         121 :     // Must be a constant.
    1967             :     if (!CE) return false;
    1968          44 :     return isValidNEONi32vmovImm(~CE->getValue());
    1969             :   }
    1970          44 : 
    1971             :   bool isNEONi64splat() const {
    1972          77 :     if (!isImm()) return false;
    1973             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1974          77 :     // Must be a constant.
    1975             :     if (!CE) return false;
    1976             :     uint64_t Value = CE->getValue();
    1977         320 :     // i64 value with each byte being either 0 or 0xff.
    1978         227 :     for (unsigned i = 0; i < 8; ++i, Value >>= 8)
    1979             :       if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
    1980         298 :     return true;
    1981             :   }
    1982         207 : 
    1983             :   template<int64_t Angle, int64_t Remainder>
    1984             :   bool isComplexRotation() const {
    1985             :     if (!isImm()) return false;
    1986         207 : 
    1987             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    1988             :     if (!CE) return false;
    1989         140 :     uint64_t Value = CE->getValue();
    1990         140 : 
    1991          84 :     return (Value % Angle == Remainder && Value <= 270);
    1992             :   }
    1993             : 
    1994          84 :   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
    1995             :     // Add as immediates when possible.  Null MCExpr = 0.
    1996             :     if (!Expr)
    1997             :       Inst.addOperand(MCOperand::createImm(0));
    1998         338 :     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
    1999         172 :       Inst.addOperand(MCOperand::createImm(CE->getValue()));
    2000             :     else
    2001             :       Inst.addOperand(MCOperand::createExpr(Expr));
    2002         172 :   }
    2003             : 
    2004         684 :   void addARMBranchTargetOperands(MCInst &Inst, unsigned N) const {
    2005         634 :     assert(N == 1 && "Invalid number of operands!");
    2006             :     addExpr(Inst, getImm());
    2007             :   }
    2008             : 
    2009             :   void addThumbBranchTargetOperands(MCInst &Inst, unsigned N) const {
    2010             :     assert(N == 1 && "Invalid number of operands!");
    2011         652 :     addExpr(Inst, getImm());
    2012             :   }
    2013         460 : 
    2014             :   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
    2015         460 :     assert(N == 2 && "Invalid number of operands!");
    2016             :     Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
    2017         460 :     unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
    2018             :     Inst.addOperand(MCOperand::createReg(RegNum));
    2019             :   }
    2020           0 : 
    2021             :   void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
    2022           0 :     assert(N == 1 && "Invalid number of operands!");
    2023           0 :     Inst.addOperand(MCOperand::createImm(getCoproc()));
    2024             :   }
    2025           0 : 
    2026             :   void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
    2027           0 :     assert(N == 1 && "Invalid number of operands!");
    2028           0 :     Inst.addOperand(MCOperand::createImm(getCoproc()));
    2029             :   }
    2030           0 : 
    2031             :   void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
    2032         563 :     assert(N == 1 && "Invalid number of operands!");
    2033           0 :     Inst.addOperand(MCOperand::createImm(CoprocOption.Val));
    2034             :   }
    2035           0 : 
    2036             :   void addITMaskOperands(MCInst &Inst, unsigned N) const {
    2037         253 :     assert(N == 1 && "Invalid number of operands!");
    2038           0 :     Inst.addOperand(MCOperand::createImm(ITMask.Mask));
    2039             :   }
    2040           0 : 
    2041             :   void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
    2042           0 :     assert(N == 1 && "Invalid number of operands!");
    2043           0 :     Inst.addOperand(MCOperand::createImm(unsigned(getCondCode())));
    2044           0 :   }
    2045           0 : 
    2046             :   void addCCOutOperands(MCInst &Inst, unsigned N) const {
    2047           0 :     assert(N == 1 && "Invalid number of operands!");
    2048             :     Inst.addOperand(MCOperand::createReg(getReg()));
    2049        1400 :   }
    2050           0 : 
    2051             :   void addRegOperands(MCInst &Inst, unsigned N) const {
    2052           0 :     assert(N == 1 && "Invalid number of operands!");
    2053             :     Inst.addOperand(MCOperand::createReg(getReg()));
    2054        1521 :   }
    2055           0 : 
    2056             :   void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
    2057           0 :     assert(N == 3 && "Invalid number of operands!");
    2058             :     assert(isRegShiftedReg() &&
    2059         142 :            "addRegShiftedRegOperands() on non-RegShiftedReg!");
    2060           0 :     Inst.addOperand(MCOperand::createReg(RegShiftedReg.SrcReg));
    2061             :     Inst.addOperand(MCOperand::createReg(RegShiftedReg.ShiftReg));
    2062           0 :     Inst.addOperand(MCOperand::createImm(
    2063             :       ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
    2064        5514 :   }
    2065           0 : 
    2066             :   void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
    2067           0 :     assert(N == 2 && "Invalid number of operands!");
    2068             :     assert(isRegShiftedImm() &&
    2069        5514 :            "addRegShiftedImmOperands() on non-RegShiftedImm!");
    2070           0 :     Inst.addOperand(MCOperand::createReg(RegShiftedImm.SrcReg));
    2071             :     // Shift of #32 is encoded as 0 where permitted
    2072           0 :     unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
    2073             :     Inst.addOperand(MCOperand::createImm(
    2074        5169 :       ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
    2075           0 :   }
    2076             : 
    2077           0 :   void addShifterImmOperands(MCInst &Inst, unsigned N) const {
    2078             :     assert(N == 1 && "Invalid number of operands!");
    2079       37697 :     Inst.addOperand(MCOperand::createImm((ShifterImm.isASR << 5) |
    2080           0 :                                          ShifterImm.Imm));
    2081             :   }
    2082           0 : 
    2083             :   void addRegListOperands(MCInst &Inst, unsigned N) const {
    2084             :     assert(N == 1 && "Invalid number of operands!");
    2085             :     const SmallVectorImpl<unsigned> &RegList = getRegList();
    2086           0 :     for (SmallVectorImpl<unsigned>::const_iterator
    2087           0 :            I = RegList.begin(), E = RegList.end(); I != E; ++I)
    2088           0 :       Inst.addOperand(MCOperand::createReg(*I));
    2089           0 :   }
    2090           0 : 
    2091             :   void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
    2092           0 :     addRegListOperands(Inst, N);
    2093             :   }
    2094             : 
    2095             :   void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
    2096           0 :     addRegListOperands(Inst, N);
    2097             :   }
    2098           0 : 
    2099           0 :   void addRotImmOperands(MCInst &Inst, unsigned N) const {
    2100           0 :     assert(N == 1 && "Invalid number of operands!");
    2101           0 :     // Encoded as val>>3. The printer handles display as 8, 16, 24.
    2102             :     Inst.addOperand(MCOperand::createImm(RotImm.Imm >> 3));
    2103           0 :   }
    2104             : 
    2105          44 :   void addModImmOperands(MCInst &Inst, unsigned N) const {
    2106          44 :     assert(N == 1 && "Invalid number of operands!");
    2107           0 : 
    2108             :     // Support for fixups (MCFixup)
    2109           0 :     if (isImm())
    2110             :       return addImmOperands(Inst, N);
    2111             : 
    2112           0 :     Inst.addOperand(MCOperand::createImm(ModImm.Bits | (ModImm.Rot << 7)));
    2113           0 :   }
    2114           0 : 
    2115           0 :   void addModImmNotOperands(MCInst &Inst, unsigned N) const {
    2116             :     assert(N == 1 && "Invalid number of operands!");
    2117           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2118          67 :     uint32_t Enc = ARM_AM::getSOImmVal(~CE->getValue());
    2119           0 :     Inst.addOperand(MCOperand::createImm(Enc));
    2120             :   }
    2121           0 : 
    2122          12 :   void addModImmNegOperands(MCInst &Inst, unsigned N) const {
    2123           0 :     assert(N == 1 && "Invalid number of operands!");
    2124             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2125           0 :     uint32_t Enc = ARM_AM::getSOImmVal(-CE->getValue());
    2126             :     Inst.addOperand(MCOperand::createImm(Enc));
    2127             :   }
    2128         330 : 
    2129           0 :   void addThumbModImmNeg8_255Operands(MCInst &Inst, unsigned N) const {
    2130             :     assert(N == 1 && "Invalid number of operands!");
    2131           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2132             :     uint32_t Val = -CE->getValue();
    2133             :     Inst.addOperand(MCOperand::createImm(Val));
    2134             :   }
    2135           0 : 
    2136           0 :   void addThumbModImmNeg1_7Operands(MCInst &Inst, unsigned N) const {
    2137             :     assert(N == 1 && "Invalid number of operands!");
    2138           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2139             :     uint32_t Val = -CE->getValue();
    2140             :     Inst.addOperand(MCOperand::createImm(Val));
    2141           0 :   }
    2142             : 
    2143           0 :   void addBitfieldOperands(MCInst &Inst, unsigned N) const {
    2144           0 :     assert(N == 1 && "Invalid number of operands!");
    2145           0 :     // Munge the lsb/width into a bitfield mask.
    2146           0 :     unsigned lsb = Bitfield.LSB;
    2147             :     unsigned width = Bitfield.Width;
    2148           0 :     // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
    2149             :     uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
    2150           0 :                       (32 - (lsb + width)));
    2151           0 :     Inst.addOperand(MCOperand::createImm(Mask));
    2152           0 :   }
    2153           0 : 
    2154             :   void addImmOperands(MCInst &Inst, unsigned N) const {
    2155           0 :     assert(N == 1 && "Invalid number of operands!");
    2156             :     addExpr(Inst, getImm());
    2157           0 :   }
    2158           0 : 
    2159           0 :   void addFBits16Operands(MCInst &Inst, unsigned N) const {
    2160           0 :     assert(N == 1 && "Invalid number of operands!");
    2161             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2162           0 :     Inst.addOperand(MCOperand::createImm(16 - CE->getValue()));
    2163             :   }
    2164           0 : 
    2165           0 :   void addFBits32Operands(MCInst &Inst, unsigned N) const {
    2166           0 :     assert(N == 1 && "Invalid number of operands!");
    2167           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2168             :     Inst.addOperand(MCOperand::createImm(32 - CE->getValue()));
    2169           0 :   }
    2170             : 
    2171             :   void addFPImmOperands(MCInst &Inst, unsigned N) const {
    2172           0 :     assert(N == 1 && "Invalid number of operands!");
    2173           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2174             :     int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
    2175           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2176           0 :   }
    2177           0 : 
    2178           0 :   void addImm8s4Operands(MCInst &Inst, unsigned N) const {
    2179             :     assert(N == 1 && "Invalid number of operands!");
    2180           0 :     // FIXME: We really want to scale the value here, but the LDRD/STRD
    2181             :     // instruction don't encode operands that way yet.
    2182        4500 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2183           0 :     Inst.addOperand(MCOperand::createImm(CE->getValue()));
    2184             :   }
    2185           0 : 
    2186             :   void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
    2187           0 :     assert(N == 1 && "Invalid number of operands!");
    2188           0 :     // The immediate is scaled by four in the encoding and is stored
    2189           0 :     // in the MCInst as such. Lop off the low two bits here.
    2190             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2191           0 :     Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
    2192             :   }
    2193           0 : 
    2194           0 :   void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
    2195           0 :     assert(N == 1 && "Invalid number of operands!");
    2196             :     // The immediate is scaled by four in the encoding and is stored
    2197           0 :     // in the MCInst as such. Lop off the low two bits here.
    2198             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2199           0 :     Inst.addOperand(MCOperand::createImm(-(CE->getValue() / 4)));
    2200           0 :   }
    2201           0 : 
    2202           0 :   void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
    2203             :     assert(N == 1 && "Invalid number of operands!");
    2204             :     // The immediate is scaled by four in the encoding and is stored
    2205             :     // in the MCInst as such. Lop off the low two bits here.
    2206             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2207             :     Inst.addOperand(MCOperand::createImm(CE->getValue() / 4));
    2208             :   }
    2209             : 
    2210             :   void addImm1_16Operands(MCInst &Inst, unsigned N) const {
    2211             :     assert(N == 1 && "Invalid number of operands!");
    2212           0 :     // The constant encodes as the immediate-1, and we store in the instruction
    2213             :     // the bits as encoded, so subtract off one here.
    2214             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2215             :     Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
    2216           0 :   }
    2217           0 : 
    2218           0 :   void addImm1_32Operands(MCInst &Inst, unsigned N) const {
    2219             :     assert(N == 1 && "Invalid number of operands!");
    2220           0 :     // The constant encodes as the immediate-1, and we store in the instruction
    2221             :     // the bits as encoded, so subtract off one here.
    2222             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2223             :     Inst.addOperand(MCOperand::createImm(CE->getValue() - 1));
    2224           0 :   }
    2225           0 : 
    2226           0 :   void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
    2227             :     assert(N == 1 && "Invalid number of operands!");
    2228           0 :     // The constant encodes as the immediate, except for 32, which encodes as
    2229             :     // zero.
    2230             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2231             :     unsigned Imm = CE->getValue();
    2232           0 :     Inst.addOperand(MCOperand::createImm((Imm == 32 ? 0 : Imm)));
    2233           0 :   }
    2234           0 : 
    2235             :   void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
    2236           0 :     assert(N == 1 && "Invalid number of operands!");
    2237             :     // An ASR value of 32 encodes as 0, so that's how we want to add it to
    2238             :     // the instruction as well.
    2239             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2240           0 :     int Val = CE->getValue();
    2241           0 :     Inst.addOperand(MCOperand::createImm(Val == 32 ? 0 : Val));
    2242           0 :   }
    2243             : 
    2244           0 :   void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
    2245             :     assert(N == 1 && "Invalid number of operands!");
    2246             :     // The operand is actually a t2_so_imm, but we have its bitwise
    2247             :     // negation in the assembly source, so twiddle it here.
    2248           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2249           0 :     Inst.addOperand(MCOperand::createImm(~(uint32_t)CE->getValue()));
    2250           0 :   }
    2251             : 
    2252             :   void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
    2253             :     assert(N == 1 && "Invalid number of operands!");
    2254             :     // The operand is actually a t2_so_imm, but we have its
    2255             :     // negation in the assembly source, so twiddle it here.
    2256             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2257             :     Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
    2258             :   }
    2259             : 
    2260             :   void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
    2261           0 :     assert(N == 1 && "Invalid number of operands!");
    2262             :     // The operand is actually an imm0_4095, but we have its
    2263             :     // negation in the assembly source, so twiddle it here.
    2264             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2265           0 :     Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
    2266           0 :   }
    2267           0 : 
    2268           0 :   void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
    2269             :     if(const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
    2270           0 :       Inst.addOperand(MCOperand::createImm(CE->getValue() >> 2));
    2271             :       return;
    2272             :     }
    2273             : 
    2274           0 :     const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
    2275           0 :     assert(SR && "Unknown value type!");
    2276           0 :     Inst.addOperand(MCOperand::createExpr(SR));
    2277             :   }
    2278           0 : 
    2279             :   void addThumbMemPCOperands(MCInst &Inst, unsigned N) const {
    2280             :     assert(N == 1 && "Invalid number of operands!");
    2281             :     if (isImm()) {
    2282           0 :       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2283           0 :       if (CE) {
    2284           0 :         Inst.addOperand(MCOperand::createImm(CE->getValue()));
    2285             :         return;
    2286           0 :       }
    2287             : 
    2288             :       const MCSymbolRefExpr *SR = dyn_cast<MCSymbolRefExpr>(Imm.Val);
    2289             : 
    2290           0 :       assert(SR && "Unknown value type!");
    2291           0 :       Inst.addOperand(MCOperand::createExpr(SR));
    2292           0 :       return;
    2293             :     }
    2294           0 : 
    2295           0 :     assert(isMem()  && "Unknown value type!");
    2296           0 :     assert(isa<MCConstantExpr>(Memory.OffsetImm) && "Unknown value type!");
    2297           0 :     Inst.addOperand(MCOperand::createImm(Memory.OffsetImm->getValue()));
    2298             :   }
    2299             : 
    2300             :   void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
    2301             :     assert(N == 1 && "Invalid number of operands!");
    2302           0 :     Inst.addOperand(MCOperand::createImm(unsigned(getMemBarrierOpt())));
    2303             :   }
    2304             : 
    2305           0 :   void addInstSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
    2306             :     assert(N == 1 && "Invalid number of operands!");
    2307           0 :     Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
    2308           0 :   }
    2309             : 
    2310           0 :   void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
    2311           0 :     assert(N == 1 && "Invalid number of operands!");
    2312             :     Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
    2313             :   }
    2314             : 
    2315             :   void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
    2316             :     assert(N == 1 && "Invalid number of operands!");
    2317           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2318           0 :   }
    2319             : 
    2320             :   void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
    2321             :     assert(N == 1 && "Invalid number of operands!");
    2322             :     int32_t Imm = Memory.OffsetImm->getValue();
    2323           0 :     Inst.addOperand(MCOperand::createImm(Imm));
    2324             :   }
    2325             : 
    2326           0 :   void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
    2327             :     assert(N == 1 && "Invalid number of operands!");
    2328         256 :     assert(isImm() && "Not an immediate!");
    2329           0 : 
    2330             :     // If we have an immediate that's not a constant, treat it as a label
    2331           0 :     // reference needing a fixup.
    2332             :     if (!isa<MCConstantExpr>(getImm())) {
    2333          18 :       Inst.addOperand(MCOperand::createExpr(getImm()));
    2334           0 :       return;
    2335             :     }
    2336           0 : 
    2337             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2338           2 :     int Val = CE->getValue();
    2339           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2340             :   }
    2341           0 : 
    2342             :   void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
    2343        1066 :     assert(N == 2 && "Invalid number of operands!");
    2344           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2345             :     Inst.addOperand(MCOperand::createImm(Memory.Alignment));
    2346           0 :   }
    2347             : 
    2348          53 :   void addDupAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
    2349          53 :     addAlignedMemoryOperands(Inst, N);
    2350           0 :   }
    2351             : 
    2352           0 :   void addAlignedMemoryNoneOperands(MCInst &Inst, unsigned N) const {
    2353             :     addAlignedMemoryOperands(Inst, N);
    2354             :   }
    2355             : 
    2356             :   void addAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
    2357             :     addAlignedMemoryOperands(Inst, N);
    2358           0 :   }
    2359           0 : 
    2360           0 :   void addDupAlignedMemory16Operands(MCInst &Inst, unsigned N) const {
    2361             :     addAlignedMemoryOperands(Inst, N);
    2362             :   }
    2363             : 
    2364           0 :   void addAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
    2365           0 :     addAlignedMemoryOperands(Inst, N);
    2366             :   }
    2367             : 
    2368           0 :   void addDupAlignedMemory32Operands(MCInst &Inst, unsigned N) const {
    2369             :     addAlignedMemoryOperands(Inst, N);
    2370           0 :   }
    2371           0 : 
    2372           0 :   void addAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
    2373             :     addAlignedMemoryOperands(Inst, N);
    2374           0 :   }
    2375          48 : 
    2376           0 :   void addDupAlignedMemory64Operands(MCInst &Inst, unsigned N) const {
    2377             :     addAlignedMemoryOperands(Inst, N);
    2378           0 :   }
    2379          80 : 
    2380           0 :   void addAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
    2381             :     addAlignedMemoryOperands(Inst, N);
    2382           0 :   }
    2383          38 : 
    2384           0 :   void addDupAlignedMemory64or128Operands(MCInst &Inst, unsigned N) const {
    2385             :     addAlignedMemoryOperands(Inst, N);
    2386           0 :   }
    2387          24 : 
    2388           0 :   void addAlignedMemory64or128or256Operands(MCInst &Inst, unsigned N) const {
    2389             :     addAlignedMemoryOperands(Inst, N);
    2390           0 :   }
    2391          66 : 
    2392           0 :   void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
    2393             :     assert(N == 3 && "Invalid number of operands!");
    2394           0 :     int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
    2395          42 :     if (!Memory.OffsetRegNum) {
    2396           0 :       ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
    2397             :       // Special case for #-0
    2398           0 :       if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
    2399         346 :       if (Val < 0) Val = -Val;
    2400           0 :       Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
    2401             :     } else {
    2402           0 :       // For register offset, we encode the shift type and negation flag
    2403          36 :       // here.
    2404           0 :       Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
    2405             :                               Memory.ShiftImm, Memory.ShiftType);
    2406           0 :     }
    2407         289 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2408           0 :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2409             :     Inst.addOperand(MCOperand::createImm(Val));
    2410           0 :   }
    2411          24 : 
    2412           0 :   void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
    2413             :     assert(N == 2 && "Invalid number of operands!");
    2414           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2415         393 :     assert(CE && "non-constant AM2OffsetImm operand!");
    2416           0 :     int32_t Val = CE->getValue();
    2417             :     ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
    2418             :     // Special case for #-0
    2419             :     if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
    2420             :     if (Val < 0) Val = -Val;
    2421             :     Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
    2422             :     Inst.addOperand(MCOperand::createReg(0));
    2423             :     Inst.addOperand(MCOperand::createImm(Val));
    2424             :   }
    2425             : 
    2426             :   void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
    2427             :     assert(N == 3 && "Invalid number of operands!");
    2428             :     // If we have an immediate that's not a constant, treat it as a label
    2429             :     // reference needing a fixup. If it is a constant, it's something else
    2430             :     // and we reject it.
    2431             :     if (isImm()) {
    2432             :       Inst.addOperand(MCOperand::createExpr(getImm()));
    2433             :       Inst.addOperand(MCOperand::createReg(0));
    2434             :       Inst.addOperand(MCOperand::createImm(0));
    2435             :       return;
    2436             :     }
    2437             : 
    2438           0 :     int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
    2439             :     if (!Memory.OffsetRegNum) {
    2440           0 :       ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
    2441             :       // Special case for #-0
    2442           0 :       if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
    2443           0 :       if (Val < 0) Val = -Val;
    2444             :       Val = ARM_AM::getAM3Opc(AddSub, Val);
    2445           0 :     } else {
    2446           0 :       // For register offset, we encode the shift type and negation flag
    2447           0 :       // here.
    2448           0 :       Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
    2449           0 :     }
    2450           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2451             :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2452           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2453             :   }
    2454             : 
    2455             :   void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
    2456             :     assert(N == 2 && "Invalid number of operands!");
    2457           0 :     if (Kind == k_PostIndexRegister) {
    2458           0 :       int32_t Val =
    2459           0 :         ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
    2460           0 :       Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
    2461           0 :       Inst.addOperand(MCOperand::createImm(Val));
    2462             :       return;
    2463             :     }
    2464           0 : 
    2465           0 :     // Constant offset.
    2466           0 :     const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
    2467             :     int32_t Val = CE->getValue();
    2468           0 :     ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
    2469           0 :     // Special case for #-0
    2470             :     if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
    2471             :     if (Val < 0) Val = -Val;
    2472             :     Val = ARM_AM::getAM3Opc(AddSub, Val);
    2473             :     Inst.addOperand(MCOperand::createReg(0));
    2474           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2475             :   }
    2476           0 : 
    2477           0 :   void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
    2478           0 :     assert(N == 2 && "Invalid number of operands!");
    2479             :     // If we have an immediate that's not a constant, treat it as a label
    2480             :     // reference needing a fixup. If it is a constant, it's something else
    2481           0 :     // and we reject it.
    2482             :     if (isImm()) {
    2483           0 :       Inst.addOperand(MCOperand::createExpr(getImm()));
    2484             :       Inst.addOperand(MCOperand::createImm(0));
    2485           0 :       return;
    2486           0 :     }
    2487           0 : 
    2488           0 :     // The lower two bits are always zero and as such are not encoded.
    2489             :     int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
    2490             :     ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
    2491             :     // Special case for #-0
    2492           0 :     if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
    2493           0 :     if (Val < 0) Val = -Val;
    2494           0 :     Val = ARM_AM::getAM5Opc(AddSub, Val);
    2495             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2496           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2497           0 :   }
    2498             : 
    2499           0 :   void addAddrMode5FP16Operands(MCInst &Inst, unsigned N) const {
    2500           0 :     assert(N == 2 && "Invalid number of operands!");
    2501             :     // If we have an immediate that's not a constant, treat it as a label
    2502             :     // reference needing a fixup. If it is a constant, it's something else
    2503           0 :     // and we reject it.
    2504             :     if (isImm()) {
    2505             :       Inst.addOperand(MCOperand::createExpr(getImm()));
    2506             :       Inst.addOperand(MCOperand::createImm(0));
    2507             :       return;
    2508           0 :     }
    2509           0 : 
    2510           0 :     // The lower bit is always zero and as such is not encoded.
    2511           0 :     int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 2 : 0;
    2512             :     ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
    2513             :     // Special case for #-0
    2514             :     if (Val == std::numeric_limits<int32_t>::min()) Val = 0;
    2515           0 :     if (Val < 0) Val = -Val;
    2516           0 :     Val = ARM_AM::getAM5FP16Opc(AddSub, Val);
    2517             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2518           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2519           0 :   }
    2520             : 
    2521           0 :   void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
    2522           0 :     assert(N == 2 && "Invalid number of operands!");
    2523             :     // If we have an immediate that's not a constant, treat it as a label
    2524             :     // reference needing a fixup. If it is a constant, it's something else
    2525           0 :     // and we reject it.
    2526             :     if (isImm()) {
    2527             :       Inst.addOperand(MCOperand::createExpr(getImm()));
    2528             :       Inst.addOperand(MCOperand::createImm(0));
    2529             :       return;
    2530           0 :     }
    2531           0 : 
    2532           0 :     int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
    2533           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2534             :     Inst.addOperand(MCOperand::createImm(Val));
    2535             :   }
    2536             : 
    2537           0 :   void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
    2538           0 :     assert(N == 2 && "Invalid number of operands!");
    2539             :     // The lower two bits are always zero and as such are not encoded.
    2540           0 :     int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
    2541           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2542             :     Inst.addOperand(MCOperand::createImm(Val));
    2543           0 :   }
    2544           0 : 
    2545             :   void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
    2546             :     assert(N == 2 && "Invalid number of operands!");
    2547           0 :     int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
    2548             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2549             :     Inst.addOperand(MCOperand::createImm(Val));
    2550             :   }
    2551             : 
    2552           0 :   void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
    2553           0 :     addMemImm8OffsetOperands(Inst, N);
    2554           0 :   }
    2555           0 : 
    2556             :   void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
    2557             :     addMemImm8OffsetOperands(Inst, N);
    2558           0 :   }
    2559           0 : 
    2560           0 :   void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
    2561             :     assert(N == 2 && "Invalid number of operands!");
    2562             :     // If this is an immediate, it's a label reference.
    2563           0 :     if (isImm()) {
    2564             :       addExpr(Inst, getImm());
    2565             :       Inst.addOperand(MCOperand::createImm(0));
    2566           0 :       return;
    2567           0 :     }
    2568           0 : 
    2569           0 :     // Otherwise, it's a normal memory reg+offset.
    2570             :     int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
    2571           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2572             :     Inst.addOperand(MCOperand::createImm(Val));
    2573           0 :   }
    2574           0 : 
    2575           0 :   void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
    2576           0 :     assert(N == 2 && "Invalid number of operands!");
    2577             :     // If this is an immediate, it's a label reference.
    2578           0 :     if (isImm()) {
    2579          42 :       addExpr(Inst, getImm());
    2580           0 :       Inst.addOperand(MCOperand::createImm(0));
    2581             :       return;
    2582           0 :     }
    2583          38 : 
    2584           0 :     // Otherwise, it's a normal memory reg+offset.
    2585             :     int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
    2586           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2587             :     Inst.addOperand(MCOperand::createImm(Val));
    2588             :   }
    2589           0 : 
    2590           0 :   void addConstPoolAsmImmOperands(MCInst &Inst, unsigned N) const {
    2591           0 :     assert(N == 1 && "Invalid number of operands!");
    2592           0 :     // This is container for the immediate that we will create the constant
    2593             :     // pool from
    2594             :     addExpr(Inst, getConstantPoolImm());
    2595             :     return;
    2596           0 :   }
    2597           0 : 
    2598           0 :   void addMemTBBOperands(MCInst &Inst, unsigned N) const {
    2599             :     assert(N == 2 && "Invalid number of operands!");
    2600             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2601           0 :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2602             :   }
    2603             : 
    2604           0 :   void addMemTBHOperands(MCInst &Inst, unsigned N) const {
    2605           0 :     assert(N == 2 && "Invalid number of operands!");
    2606           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2607           0 :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2608             :   }
    2609             : 
    2610             :   void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
    2611           0 :     assert(N == 3 && "Invalid number of operands!");
    2612           0 :     unsigned Val =
    2613           0 :       ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
    2614             :                         Memory.ShiftImm, Memory.ShiftType);
    2615             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2616           0 :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2617             :     Inst.addOperand(MCOperand::createImm(Val));
    2618             :   }
    2619             : 
    2620         549 :   void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
    2621           0 :     assert(N == 3 && "Invalid number of operands!");
    2622             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2623             :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2624           0 :     Inst.addOperand(MCOperand::createImm(Memory.ShiftImm));
    2625             :   }
    2626           0 : 
    2627           0 :   void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
    2628           0 :     assert(N == 2 && "Invalid number of operands!");
    2629             :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2630           0 :     Inst.addOperand(MCOperand::createReg(Memory.OffsetRegNum));
    2631             :   }
    2632           0 : 
    2633           0 :   void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
    2634           0 :     assert(N == 2 && "Invalid number of operands!");
    2635             :     int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
    2636           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2637             :     Inst.addOperand(MCOperand::createImm(Val));
    2638             :   }
    2639           0 : 
    2640           0 :   void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
    2641           0 :     assert(N == 2 && "Invalid number of operands!");
    2642           0 :     int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
    2643           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2644           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2645             :   }
    2646           0 : 
    2647             :   void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
    2648           0 :     assert(N == 2 && "Invalid number of operands!");
    2649           0 :     int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
    2650           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2651           0 :     Inst.addOperand(MCOperand::createImm(Val));
    2652             :   }
    2653           0 : 
    2654             :   void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
    2655           0 :     assert(N == 2 && "Invalid number of operands!");
    2656           0 :     int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
    2657           0 :     Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
    2658             :     Inst.addOperand(MCOperand::createImm(Val));
    2659           0 :   }
    2660             : 
    2661           0 :   void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
    2662           0 :     assert(N == 1 && "Invalid number of operands!");
    2663           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2664           0 :     assert(CE && "non-constant post-idx-imm8 operand!");
    2665             :     int Imm = CE->getValue();
    2666           0 :     bool isAdd = Imm >= 0;
    2667             :     if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
    2668           0 :     Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
    2669           0 :     Inst.addOperand(MCOperand::createImm(Imm));
    2670           0 :   }
    2671           0 : 
    2672             :   void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
    2673           0 :     assert(N == 1 && "Invalid number of operands!");
    2674             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2675           0 :     assert(CE && "non-constant post-idx-imm8s4 operand!");
    2676           0 :     int Imm = CE->getValue();
    2677           0 :     bool isAdd = Imm >= 0;
    2678           0 :     if (Imm == std::numeric_limits<int32_t>::min()) Imm = 0;
    2679             :     // Immediate is scaled by 4.
    2680           0 :     Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
    2681             :     Inst.addOperand(MCOperand::createImm(Imm));
    2682           0 :   }
    2683           0 : 
    2684           0 :   void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
    2685           0 :     assert(N == 2 && "Invalid number of operands!");
    2686             :     Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
    2687           0 :     Inst.addOperand(MCOperand::createImm(PostIdxReg.isAdd));
    2688             :   }
    2689           0 : 
    2690             :   void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
    2691           0 :     assert(N == 2 && "Invalid number of operands!");
    2692           0 :     Inst.addOperand(MCOperand::createReg(PostIdxReg.RegNum));
    2693           0 :     // The sign, shift type, and shift amount are encoded in a single operand
    2694           0 :     // using the AM2 encoding helpers.
    2695           0 :     ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
    2696           0 :     unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
    2697             :                                      PostIdxReg.ShiftTy);
    2698           0 :     Inst.addOperand(MCOperand::createImm(Imm));
    2699             :   }
    2700           0 : 
    2701             :   void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
    2702           0 :     assert(N == 1 && "Invalid number of operands!");
    2703           0 :     Inst.addOperand(MCOperand::createImm(unsigned(getMSRMask())));
    2704           0 :   }
    2705             : 
    2706           0 :   void addBankedRegOperands(MCInst &Inst, unsigned N) const {
    2707           0 :     assert(N == 1 && "Invalid number of operands!");
    2708           0 :     Inst.addOperand(MCOperand::createImm(unsigned(getBankedReg())));
    2709             :   }
    2710           0 : 
    2711             :   void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
    2712           0 :     assert(N == 1 && "Invalid number of operands!");
    2713           0 :     Inst.addOperand(MCOperand::createImm(unsigned(getProcIFlags())));
    2714           0 :   }
    2715             : 
    2716           0 :   void addVecListOperands(MCInst &Inst, unsigned N) const {
    2717             :     assert(N == 1 && "Invalid number of operands!");
    2718           0 :     Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
    2719             :   }
    2720             : 
    2721           0 :   void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
    2722           0 :     assert(N == 2 && "Invalid number of operands!");
    2723           0 :     Inst.addOperand(MCOperand::createReg(VectorList.RegNum));
    2724           0 :     Inst.addOperand(MCOperand::createImm(VectorList.LaneIndex));
    2725           0 :   }
    2726             : 
    2727           0 :   void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
    2728             :     assert(N == 1 && "Invalid number of operands!");
    2729         334 :     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
    2730           0 :   }
    2731             : 
    2732           0 :   void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
    2733             :     assert(N == 1 && "Invalid number of operands!");
    2734         198 :     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
    2735           0 :   }
    2736             : 
    2737           0 :   void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
    2738             :     assert(N == 1 && "Invalid number of operands!");
    2739          71 :     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
    2740           0 :   }
    2741             : 
    2742           0 :   void addVectorIndex64Operands(MCInst &Inst, unsigned N) const {
    2743             :     assert(N == 1 && "Invalid number of operands!");
    2744        1075 :     Inst.addOperand(MCOperand::createImm(getVectorIndex()));
    2745           0 :   }
    2746             : 
    2747           0 :   void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
    2748             :     assert(N == 1 && "Invalid number of operands!");
    2749           0 :     // The immediate encodes the type of constant as well as the value.
    2750           0 :     // Mask in that this is an i8 splat.
    2751           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2752             :     Inst.addOperand(MCOperand::createImm(CE->getValue() | 0xe00));
    2753           0 :   }
    2754             : 
    2755          22 :   void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
    2756           0 :     assert(N == 1 && "Invalid number of operands!");
    2757             :     // The immediate encodes the type of constant as well as the value.
    2758           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2759             :     unsigned Value = CE->getValue();
    2760         134 :     Value = ARM_AM::encodeNEONi16splat(Value);
    2761           0 :     Inst.addOperand(MCOperand::createImm(Value));
    2762             :   }
    2763           0 : 
    2764             :   void addNEONi16splatNotOperands(MCInst &Inst, unsigned N) const {
    2765         175 :     assert(N == 1 && "Invalid number of operands!");
    2766           0 :     // The immediate encodes the type of constant as well as the value.
    2767             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2768           0 :     unsigned Value = CE->getValue();
    2769             :     Value = ARM_AM::encodeNEONi16splat(~Value & 0xffff);
    2770          40 :     Inst.addOperand(MCOperand::createImm(Value));
    2771           0 :   }
    2772             : 
    2773           0 :   void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
    2774             :     assert(N == 1 && "Invalid number of operands!");
    2775             :     // The immediate encodes the type of constant as well as the value.
    2776             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2777           0 :     unsigned Value = CE->getValue();
    2778           0 :     Value = ARM_AM::encodeNEONi32splat(Value);
    2779           0 :     Inst.addOperand(MCOperand::createImm(Value));
    2780             :   }
    2781           0 : 
    2782             :   void addNEONi32splatNotOperands(MCInst &Inst, unsigned N) const {
    2783             :     assert(N == 1 && "Invalid number of operands!");
    2784           0 :     // The immediate encodes the type of constant as well as the value.
    2785           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2786             :     unsigned Value = CE->getValue();
    2787           0 :     Value = ARM_AM::encodeNEONi32splat(~Value);
    2788           0 :     Inst.addOperand(MCOperand::createImm(Value));
    2789             :   }
    2790           0 : 
    2791             :   void addNEONi8ReplicateOperands(MCInst &Inst, bool Inv) const {
    2792             :     // The immediate encodes the type of constant as well as the value.
    2793           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2794           0 :     assert((Inst.getOpcode() == ARM::VMOVv8i8 ||
    2795           0 :             Inst.getOpcode() == ARM::VMOVv16i8) &&
    2796           0 :           "All instructions that wants to replicate non-zero byte "
    2797           0 :           "always must be replaced with VMOVv8i8 or VMOVv16i8.");
    2798             :     unsigned Value = CE->getValue();
    2799           0 :     if (Inv)
    2800             :       Value = ~Value;
    2801             :     unsigned B = Value & 0xff;
    2802           0 :     B |= 0xe00; // cmode = 0b1110
    2803           0 :     Inst.addOperand(MCOperand::createImm(B));
    2804             :   }
    2805           0 : 
    2806           0 :   void addNEONinvi8ReplicateOperands(MCInst &Inst, unsigned N) const {
    2807             :     assert(N == 1 && "Invalid number of operands!");
    2808           0 :     addNEONi8ReplicateOperands(Inst, true);
    2809             :   }
    2810             : 
    2811           0 :   static unsigned encodeNeonVMOVImmediate(unsigned Value) {
    2812           0 :     if (Value >= 256 && Value <= 0xffff)
    2813           0 :       Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
    2814           0 :     else if (Value > 0xffff && Value <= 0xffffff)
    2815           0 :       Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
    2816             :     else if (Value > 0xffffff)
    2817          18 :       Value = (Value >> 24) | 0x600;
    2818             :     return Value;
    2819          18 :   }
    2820             : 
    2821             :   void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
    2822             :     assert(N == 1 && "Invalid number of operands!");
    2823             :     // The immediate encodes the type of constant as well as the value.
    2824          18 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2825          18 :     unsigned Value = encodeNeonVMOVImmediate(CE->getValue());
    2826          10 :     Inst.addOperand(MCOperand::createImm(Value));
    2827          18 :   }
    2828          18 : 
    2829          18 :   void addNEONvmovi8ReplicateOperands(MCInst &Inst, unsigned N) const {
    2830          18 :     assert(N == 1 && "Invalid number of operands!");
    2831             :     addNEONi8ReplicateOperands(Inst, false);
    2832           0 :   }
    2833             : 
    2834          10 :   void addNEONvmovi16ReplicateOperands(MCInst &Inst, unsigned N) const {
    2835           0 :     assert(N == 1 && "Invalid number of operands!");
    2836             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2837          46 :     assert((Inst.getOpcode() == ARM::VMOVv4i16 ||
    2838          46 :             Inst.getOpcode() == ARM::VMOVv8i16 ||
    2839          18 :             Inst.getOpcode() == ARM::VMVNv4i16 ||
    2840          34 :             Inst.getOpcode() == ARM::VMVNv8i16) &&
    2841          22 :           "All instructions that want to replicate non-zero half-word "
    2842          18 :           "always must be replaced with V{MOV,MVN}v{4,8}i16.");
    2843           7 :     uint64_t Value = CE->getValue();
    2844          46 :     unsigned Elem = Value & 0xffff;
    2845             :     if (Elem >= 256)
    2846             :       Elem = (Elem >> 8) | 0x200;
    2847           0 :     Inst.addOperand(MCOperand::createImm(Elem));
    2848             :   }
    2849             : 
    2850           0 :   void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
    2851           0 :     assert(N == 1 && "Invalid number of operands!");
    2852           0 :     // The immediate encodes the type of constant as well as the value.
    2853           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2854             :     unsigned Value = encodeNeonVMOVImmediate(~CE->getValue());
    2855           0 :     Inst.addOperand(MCOperand::createImm(Value));
    2856             :   }
    2857           8 : 
    2858           0 :   void addNEONvmovi32ReplicateOperands(MCInst &Inst, unsigned N) const {
    2859             :     assert(N == 1 && "Invalid number of operands!");
    2860           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2861             :     assert((Inst.getOpcode() == ARM::VMOVv2i32 ||
    2862           0 :             Inst.getOpcode() == ARM::VMOVv4i32 ||
    2863             :             Inst.getOpcode() == ARM::VMVNv2i32 ||
    2864             :             Inst.getOpcode() == ARM::VMVNv4i32) &&
    2865             :           "All instructions that want to replicate non-zero word "
    2866             :           "always must be replaced with V{MOV,MVN}v{2,4}i32.");
    2867             :     uint64_t Value = CE->getValue();
    2868             :     unsigned Elem = encodeNeonVMOVImmediate(Value & 0xffffffff);
    2869           0 :     Inst.addOperand(MCOperand::createImm(Elem));
    2870           0 :   }
    2871           0 : 
    2872           0 :   void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
    2873           0 :     assert(N == 1 && "Invalid number of operands!");
    2874           0 :     // The immediate encodes the type of constant as well as the value.
    2875             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2876           0 :     uint64_t Value = CE->getValue();
    2877             :     unsigned Imm = 0;
    2878             :     for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
    2879           0 :       Imm |= (Value & 1) << i;
    2880           0 :     }
    2881           0 :     Inst.addOperand(MCOperand::createImm(Imm | 0x1e00));
    2882           0 :   }
    2883             : 
    2884           0 :   void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
    2885             :     assert(N == 1 && "Invalid number of operands!");
    2886           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2887             :     Inst.addOperand(MCOperand::createImm(CE->getValue() / 90));
    2888             :   }
    2889             : 
    2890             :   void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
    2891             :     assert(N == 1 && "Invalid number of operands!");
    2892             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
    2893           0 :     Inst.addOperand(MCOperand::createImm((CE->getValue() - 90) / 180));
    2894           0 :   }
    2895           0 : 
    2896           0 :   void print(raw_ostream &OS) const override;
    2897             : 
    2898           0 :   static std::unique_ptr<ARMOperand> CreateITMask(unsigned Mask, SMLoc S) {
    2899             :     auto Op = make_unique<ARMOperand>(k_ITCondMask);
    2900             :     Op->ITMask.Mask = Mask;
    2901           0 :     Op->StartLoc = S;
    2902           0 :     Op->EndLoc = S;
    2903             :     return Op;
    2904           0 :   }
    2905           0 : 
    2906             :   static std::unique_ptr<ARMOperand> CreateCondCode(ARMCC::CondCodes CC,
    2907           0 :                                                     SMLoc S) {
    2908           0 :     auto Op = make_unique<ARMOperand>(k_CondCode);
    2909             :     Op->CC.Val = CC;
    2910           0 :     Op->StartLoc = S;
    2911             :     Op->EndLoc = S;
    2912           0 :     return Op;
    2913           0 :   }
    2914           0 : 
    2915             :   static std::unique_ptr<ARMOperand> CreateCoprocNum(unsigned CopVal, SMLoc S) {
    2916           0 :     auto Op = make_unique<ARMOperand>(k_CoprocNum);
    2917             :     Op->Cop.Val = CopVal;
    2918           0 :     Op->StartLoc = S;
    2919           0 :     Op->EndLoc = S;
    2920           0 :     return Op;
    2921             :   }
    2922             : 
    2923             :   static std::unique_ptr<ARMOperand> CreateCoprocReg(unsigned CopVal, SMLoc S) {
    2924             :     auto Op = make_unique<ARMOperand>(k_CoprocReg);
    2925        2787 :     Op->Cop.Val = CopVal;
    2926        2787 :     Op->StartLoc = S;
    2927        2787 :     Op->EndLoc = S;
    2928        2787 :     return Op;
    2929             :   }
    2930             : 
    2931             :   static std::unique_ptr<ARMOperand> CreateCoprocOption(unsigned Val, SMLoc S,
    2932             :                                                         SMLoc E) {
    2933             :     auto Op = make_unique<ARMOperand>(k_CoprocOption);
    2934       23165 :     Op->Cop.Val = Val;
    2935       23165 :     Op->StartLoc = S;
    2936       23165 :     Op->EndLoc = E;
    2937       23165 :     return Op;
    2938             :   }
    2939             : 
    2940             :   static std::unique_ptr<ARMOperand> CreateCCOut(unsigned RegNum, SMLoc S) {
    2941             :     auto Op = make_unique<ARMOperand>(k_CCOut);
    2942         886 :     Op->Reg.RegNum = RegNum;
    2943         886 :     Op->StartLoc = S;
    2944         886 :     Op->EndLoc = S;
    2945         886 :     return Op;
    2946             :   }
    2947             : 
    2948             :   static std::unique_ptr<ARMOperand> CreateToken(StringRef Str, SMLoc S) {
    2949             :     auto Op = make_unique<ARMOperand>(k_Token);
    2950        1021 :     Op->Tok.Data = Str.data();
    2951        1021 :     Op->Tok.Length = Str.size();
    2952        1021 :     Op->StartLoc = S;
    2953        1021 :     Op->EndLoc = S;
    2954             :     return Op;
    2955             :   }
    2956             : 
    2957             :   static std::unique_ptr<ARMOperand> CreateReg(unsigned RegNum, SMLoc S,
    2958             :                                                SMLoc E) {
    2959          78 :     auto Op = make_unique<ARMOperand>(k_Register);
    2960          78 :     Op->Reg.RegNum = RegNum;
    2961          78 :     Op->StartLoc = S;
    2962          78 :     Op->EndLoc = E;
    2963             :     return Op;
    2964             :   }
    2965             : 
    2966             :   static std::unique_ptr<ARMOperand>
    2967        4705 :   CreateShiftedRegister(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
    2968        4705 :                         unsigned ShiftReg, unsigned ShiftImm, SMLoc S,
    2969        4705 :                         SMLoc E) {
    2970        4705 :     auto Op = make_unique<ARMOperand>(k_ShiftedRegister);
    2971             :     Op->RegShiftedReg.ShiftTy = ShTy;
    2972             :     Op->RegShiftedReg.SrcReg = SrcReg;
    2973             :     Op->RegShiftedReg.ShiftReg = ShiftReg;
    2974       37949 :     Op->RegShiftedReg.ShiftImm = ShiftImm;
    2975       37949 :     Op->StartLoc = S;
    2976       37949 :     Op->EndLoc = E;
    2977       37949 :     return Op;
    2978       37949 :   }
    2979       37949 : 
    2980       37949 :   static std::unique_ptr<ARMOperand>
    2981             :   CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy, unsigned SrcReg,
    2982             :                          unsigned ShiftImm, SMLoc S, SMLoc E) {
    2983             :     auto Op = make_unique<ARMOperand>(k_ShiftedImmediate);
    2984             :     Op->RegShiftedImm.ShiftTy = ShTy;
    2985          48 :     Op->RegShiftedImm.SrcReg = SrcReg;
    2986       34715 :     Op->RegShiftedImm.ShiftImm = ShiftImm;
    2987       34715 :     Op->StartLoc = S;
    2988       34715 :     Op->EndLoc = E;
    2989             :     return Op;
    2990             :   }
    2991             : 
    2992             :   static std::unique_ptr<ARMOperand> CreateShifterImm(bool isASR, unsigned Imm,
    2993         247 :                                                       SMLoc S, SMLoc E) {
    2994             :     auto Op = make_unique<ARMOperand>(k_ShifterImmediate);
    2995             :     Op->ShifterImm.isASR = isASR;
    2996         247 :     Op->ShifterImm.Imm = Imm;
    2997         247 :     Op->StartLoc = S;
    2998         247 :     Op->EndLoc = E;
    2999         247 :     return Op;
    3000         247 :   }
    3001         247 : 
    3002         247 :   static std::unique_ptr<ARMOperand> CreateRotImm(unsigned Imm, SMLoc S,
    3003         247 :                                                   SMLoc E) {
    3004             :     auto Op = make_unique<ARMOperand>(k_RotateImmediate);
    3005             :     Op->RotImm.Imm = Imm;
    3006             :     Op->StartLoc = S;
    3007         641 :     Op->EndLoc = E;
    3008             :     return Op;
    3009         641 :   }
    3010         641 : 
    3011         641 :   static std::unique_ptr<ARMOperand> CreateModImm(unsigned Bits, unsigned Rot,
    3012         641 :                                                   SMLoc S, SMLoc E) {
    3013         641 :     auto Op = make_unique<ARMOperand>(k_ModifiedImmediate);
    3014         641 :     Op->ModImm.Bits = Bits;
    3015         641 :     Op->ModImm.Rot = Rot;
    3016             :     Op->StartLoc = S;
    3017             :     Op->EndLoc = E;
    3018             :     return Op;
    3019             :   }
    3020          32 : 
    3021          32 :   static std::unique_ptr<ARMOperand>
    3022          32 :   CreateConstantPoolImm(const MCExpr *Val, SMLoc S, SMLoc E) {
    3023          32 :     auto Op = make_unique<ARMOperand>(k_ConstantPoolImmediate);
    3024          32 :     Op->Imm.Val = Val;
    3025             :     Op->StartLoc = S;
    3026             :     Op->EndLoc = E;
    3027             :     return Op;
    3028             :   }
    3029             : 
    3030         218 :   static std::unique_ptr<ARMOperand>
    3031         218 :   CreateBitfield(unsigned LSB, unsigned Width, SMLoc S, SMLoc E) {
    3032         218 :     auto Op = make_unique<ARMOperand>(k_BitfieldDescriptor);
    3033         218 :     Op->Bitfield.LSB = LSB;
    3034             :     Op->Bitfield.Width = Width;
    3035             :     Op->StartLoc = S;
    3036             :     Op->EndLoc = E;
    3037             :     return Op;
    3038             :   }
    3039        1089 : 
    3040        1089 :   static std::unique_ptr<ARMOperand>
    3041        1089 :   CreateRegList(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
    3042        1089 :                 SMLoc StartLoc, SMLoc EndLoc) {
    3043        1089 :     assert(Regs.size() > 0 && "RegList contains no registers?");
    3044             :     KindTy Kind = k_RegisterList;
    3045             : 
    3046             :     if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().second))
    3047             :       Kind = k_DPRRegisterList;
    3048             :     else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
    3049         388 :              contains(Regs.front().second))
    3050         388 :       Kind = k_SPRRegisterList;
    3051         388 : 
    3052         388 :     // Sort based on the register encoding values.
    3053             :     array_pod_sort(Regs.begin(), Regs.end());
    3054             : 
    3055             :     auto Op = make_unique<ARMOperand>(Kind);
    3056             :     for (SmallVectorImpl<std::pair<unsigned, unsigned>>::const_iterator
    3057             :            I = Regs.begin(), E = Regs.end(); I != E; ++I)
    3058          34 :       Op->Registers.push_back(I->second);
    3059          34 :     Op->StartLoc = StartLoc;
    3060          34 :     Op->EndLoc = EndLoc;
    3061          34 :     return Op;
    3062          34 :   }
    3063             : 
    3064             :   static std::unique_ptr<ARMOperand> CreateVectorList(unsigned RegNum,
    3065             :                                                       unsigned Count,
    3066             :                                                       bool isDoubleSpaced,
    3067         755 :                                                       SMLoc S, SMLoc E) {
    3068             :     auto Op = make_unique<ARMOperand>(k_VectorList);
    3069             :     Op->VectorList.RegNum = RegNum;
    3070             :     Op->VectorList.Count = Count;
    3071             :     Op->VectorList.isDoubleSpaced = isDoubleSpaced;
    3072         755 :     Op->StartLoc = S;
    3073             :     Op->EndLoc = E;
    3074         673 :     return Op;
    3075         673 :   }
    3076             : 
    3077             :   static std::unique_ptr<ARMOperand>
    3078             :   CreateVectorListAllLanes(unsigned RegNum, unsigned Count, bool isDoubleSpaced,
    3079             :                            SMLoc S, SMLoc E) {
    3080             :     auto Op = make_unique<ARMOperand>(k_VectorListAllLanes);
    3081         755 :     Op->VectorList.RegNum = RegNum;
    3082        2376 :     Op->VectorList.Count = Count;
    3083        3131 :     Op->VectorList.isDoubleSpaced = isDoubleSpaced;
    3084        2376 :     Op->StartLoc = S;
    3085         755 :     Op->EndLoc = E;
    3086         755 :     return Op;
    3087         755 :   }
    3088             : 
    3089             :   static std::unique_ptr<ARMOperand>
    3090        1549 :   CreateVectorListIndexed(unsigned RegNum, unsigned Count, unsigned Index,
    3091             :                           bool isDoubleSpaced, SMLoc S, SMLoc E) {
    3092             :     auto Op = make_unique<ARMOperand>(k_VectorListIndexed);
    3093             :     Op->VectorList.RegNum = RegNum;
    3094        1549 :     Op->VectorList.Count = Count;
    3095        1549 :     Op->VectorList.LaneIndex = Index;
    3096        1549 :     Op->VectorList.isDoubleSpaced = isDoubleSpaced;
    3097        1549 :     Op->StartLoc = S;
    3098        1549 :     Op->EndLoc = E;
    3099        1549 :     return Op;
    3100        1549 :   }
    3101             : 
    3102             :   static std::unique_ptr<ARMOperand>
    3103             :   CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
    3104         480 :     auto Op = make_unique<ARMOperand>(k_VectorIndex);
    3105             :     Op->VectorIndex.Val = Idx;
    3106         480 :     Op->StartLoc = S;
    3107         480 :     Op->EndLoc = E;
    3108         480 :     return Op;
    3109         480 :   }
    3110         480 : 
    3111         480 :   static std::unique_ptr<ARMOperand> CreateImm(const MCExpr *Val, SMLoc S,
    3112         480 :                                                SMLoc E) {
    3113             :     auto Op = make_unique<ARMOperand>(k_Immediate);
    3114             :     Op->Imm.Val = Val;
    3115             :     Op->StartLoc = S;
    3116         786 :     Op->EndLoc = E;
    3117             :     return Op;
    3118         786 :   }
    3119         786 : 
    3120         786 :   static std::unique_ptr<ARMOperand>
    3121         786 :   CreateMem(unsigned BaseRegNum, const MCConstantExpr *OffsetImm,
    3122         786 :             unsigned OffsetRegNum, ARM_AM::ShiftOpc ShiftType,
    3123         786 :             unsigned ShiftImm, unsigned Alignment, bool isNegative, SMLoc S,
    3124         786 :             SMLoc E, SMLoc AlignmentLoc = SMLoc()) {
    3125         786 :     auto Op = make_unique<ARMOperand>(k_Memory);
    3126             :     Op->Memory.BaseRegNum = BaseRegNum;
    3127             :     Op->Memory.OffsetImm = OffsetImm;
    3128             :     Op->Memory.OffsetRegNum = OffsetRegNum;
    3129           0 :     Op->Memory.ShiftType = ShiftType;
    3130           0 :     Op->Memory.ShiftImm = ShiftImm;
    3131         449 :     Op->Memory.Alignment = Alignment;
    3132         449 :     Op->Memory.isNegative = isNegative;
    3133         449 :     Op->StartLoc = S;
    3134           0 :     Op->EndLoc = E;
    3135             :     Op->AlignmentLoc = AlignmentLoc;
    3136             :     return Op;
    3137             :   }
    3138             : 
    3139         136 :   static std::unique_ptr<ARMOperand>
    3140        6092 :   CreatePostIdxReg(unsigned RegNum, bool isAdd, ARM_AM::ShiftOpc ShiftTy,
    3141        6092 :                    unsigned ShiftImm, SMLoc S, SMLoc E) {
    3142        6092 :     auto Op = make_unique<ARMOperand>(k_PostIndexRegister);
    3143             :     Op->PostIdxReg.RegNum = RegNum;
    3144             :     Op->PostIdxReg.isAdd = isAdd;
    3145             :     Op->PostIdxReg.ShiftTy = ShiftTy;
    3146             :     Op->PostIdxReg.ShiftImm = ShiftImm;
    3147        5380 :     Op->StartLoc = S;
    3148             :     Op->EndLoc = E;
    3149             :     return Op;
    3150             :   }
    3151        5380 : 
    3152        5380 :   static std::unique_ptr<ARMOperand> CreateMemBarrierOpt(ARM_MB::MemBOpt Opt,
    3153        5380 :                                                          SMLoc S) {
    3154        5380 :     auto Op = make_unique<ARMOperand>(k_MemBarrierOpt);
    3155        5380 :     Op->MBOpt.Val = Opt;
    3156        5380 :     Op->StartLoc = S;
    3157        5380 :     Op->EndLoc = S;
    3158        5380 :     return Op;
    3159        5380 :   }
    3160        5380 : 
    3161        5380 :   static std::unique_ptr<ARMOperand>
    3162        5380 :   CreateInstSyncBarrierOpt(ARM_ISB::InstSyncBOpt Opt, SMLoc S) {
    3163             :     auto Op = make_unique<ARMOperand>(k_InstSyncBarrierOpt);
    3164             :     Op->ISBOpt.Val = Opt;
    3165             :     Op->StartLoc = S;
    3166          76 :     Op->EndLoc = S;
    3167             :     return Op;
    3168          76 :   }
    3169          76 : 
    3170          76 :   static std::unique_ptr<ARMOperand>
    3171          76 :   CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) {
    3172          76 :     auto Op = make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
    3173          76 :     Op->TSBOpt.Val = Opt;
    3174          76 :     Op->StartLoc = S;
    3175          76 :     Op->EndLoc = S;
    3176             :     return Op;
    3177             :   }
    3178             : 
    3179             :   static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags,
    3180         256 :                                                       SMLoc S) {
    3181         256 :     auto Op = make_unique<ARMOperand>(k_ProcIFlags);
    3182         256 :     Op->IFlags.Val = IFlags;
    3183         256 :     Op->StartLoc = S;
    3184             :     Op->EndLoc = S;
    3185             :     return Op;
    3186             :   }
    3187             : 
    3188             :   static std::unique_ptr<ARMOperand> CreateMSRMask(unsigned MMask, SMLoc S) {
    3189          18 :     auto Op = make_unique<ARMOperand>(k_MSRMask);
    3190          18 :     Op->MMask.Val = MMask;
    3191          18 :     Op->StartLoc = S;
    3192          18 :     Op->EndLoc = S;
    3193             :     return Op;
    3194             :   }
    3195             : 
    3196             :   static std::unique_ptr<ARMOperand> CreateBankedReg(unsigned Reg, SMLoc S) {
    3197             :     auto Op = make_unique<ARMOperand>(k_BankedReg);
    3198           2 :     Op->BankedReg.Val = Reg;
    3199           2 :     Op->StartLoc = S;
    3200           2 :     Op->EndLoc = S;
    3201           2 :     return Op;
    3202             :   }
    3203             : };
    3204             : 
    3205             : } // end anonymous namespace.
    3206             : 
    3207          44 : void ARMOperand::print(raw_ostream &OS) const {
    3208          44 :   switch (Kind) {
    3209          44 :   case k_CondCode:
    3210          44 :     OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
    3211             :     break;
    3212             :   case k_CCOut:
    3213             :     OS << "<ccout " << getReg() << ">";
    3214             :     break;
    3215         219 :   case k_ITCondMask: {
    3216         219 :     static const char *const MaskStr[] = {
    3217         219 :       "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
    3218         219 :       "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
    3219             :     };
    3220             :     assert((ITMask.Mask & 0xf) == ITMask.Mask);
    3221             :     OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
    3222             :     break;
    3223         132 :   }
    3224         132 :   case k_CoprocNum:
    3225         132 :     OS << "<coprocessor number: " << getCoproc() << ">";
    3226         132 :     break;
    3227             :   case k_CoprocReg:
    3228             :     OS << "<coprocessor register: " << getCoproc() << ">";
    3229             :     break;
    3230             :   case k_CoprocOption:
    3231             :     OS << "<coprocessor option: " << CoprocOption.Val << ">";
    3232             :     break;
    3233           0 :   case k_MSRMask:
    3234           0 :     OS << "<mask: " << getMSRMask() << ">";
    3235           0 :     break;
    3236           0 :   case k_BankedReg:
    3237           0 :     OS << "<banked reg: " << getBankedReg() << ">";
    3238           0 :     break;
    3239           0 :   case k_Immediate:
    3240           0 :     OS << *getImm();
    3241           0 :     break;
    3242             :   case k_MemBarrierOpt:
    3243             :     OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt(), false) << ">";
    3244             :     break;
    3245             :   case k_InstSyncBarrierOpt:
    3246             :     OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
    3247           0 :     break;
    3248           0 :   case k_TraceSyncBarrierOpt:
    3249             :     OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
    3250           0 :     break;
    3251           0 :   case k_Memory:
    3252           0 :     OS << "<memory "
    3253           0 :        << " base:" << Memory.BaseRegNum;
    3254           0 :     OS << ">";
    3255           0 :     break;
    3256           0 :   case k_PostIndexRegister:
    3257           0 :     OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
    3258           0 :        << PostIdxReg.RegNum;
    3259           0 :     if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
    3260           0 :       OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
    3261           0 :          << PostIdxReg.ShiftImm;
    3262           0 :     OS << ">";
    3263           0 :     break;
    3264           0 :   case k_ProcIFlags: {
    3265           0 :     OS << "<ARM_PROC::";
    3266           0 :     unsigned IFlags = getProcIFlags();
    3267             :     for (int i=2; i >= 0; --i)
    3268           0 :       if (IFlags & (1 << i))
    3269           0 :         OS << ARM_PROC::IFlagsToString(1 << i);
    3270           0 :     OS << ">";
    3271           0 :     break;
    3272           0 :   }
    3273           0 :   case k_Register:
    3274           0 :     OS << "<register " << getReg() << ">";
    3275           0 :     break;
    3276           0 :   case k_ShifterImmediate:
    3277           0 :     OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
    3278           0 :        << " #" << ShifterImm.Imm << ">";
    3279           0 :     break;
    3280           0 :   case k_ShiftedRegister:
    3281           0 :     OS << "<so_reg_reg "
    3282           0 :        << RegShiftedReg.SrcReg << " "
    3283           0 :        << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
    3284           0 :        << " " << RegShiftedReg.ShiftReg << ">";
    3285           0 :     break;
    3286           0 :   case k_ShiftedImmediate:
    3287           0 :     OS << "<so_reg_imm "
    3288           0 :        << RegShiftedImm.SrcReg << " "
    3289           0 :        << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
    3290           0 :        << " #" << RegShiftedImm.ShiftImm << ">";
    3291           0 :     break;
    3292           0 :   case k_RotateImmediate:
    3293           0 :     OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
    3294           0 :     break;
    3295           0 :   case k_ModifiedImmediate:
    3296           0 :     OS << "<mod_imm #" << ModImm.Bits << ", #"
    3297           0 :        <<  ModImm.Rot << ")>";
    3298             :     break;
    3299           0 :   case k_ConstantPoolImmediate:
    3300           0 :     OS << "<constant_pool_imm #" << *getConstantPoolImm();
    3301           0 :     break;
    3302           0 :   case k_BitfieldDescriptor:
    3303           0 :     OS << "<bitfield " << "lsb: " << Bitfield.LSB
    3304           0 :        << ", width: " << Bitfield.Width << ">";
    3305           0 :     break;
    3306           0 :   case k_RegisterList:
    3307           0 :   case k_DPRRegisterList:
    3308           0 :   case k_SPRRegisterList: {
    3309           0 :     OS << "<register_list ";
    3310           0 : 
    3311           0 :     const SmallVectorImpl<unsigned> &RegList = getRegList();
    3312           0 :     for (SmallVectorImpl<unsigned>::const_iterator
    3313           0 :            I = RegList.begin(), E = RegList.end(); I != E; ) {
    3314           0 :       OS << *I;
    3315           0 :       if (++I < E) OS << ", ";
    3316           0 :     }
    3317           0 : 
    3318           0 :     OS << ">";
    3319           0 :     break;
    3320           0 :   }
    3321           0 :   case k_VectorList:
    3322           0 :     OS << "<vector_list " << VectorList.Count << " * "
    3323           0 :        << VectorList.RegNum << ">";
    3324           0 :     break;
    3325           0 :   case k_VectorListAllLanes:
    3326           0 :     OS << "<vector_list(all lanes) " << VectorList.Count << " * "
    3327             :        << VectorList.RegNum << ">";
    3328           0 :     break;
    3329           0 :   case k_VectorListIndexed:
    3330           0 :     OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
    3331           0 :        << VectorList.Count << " * " << VectorList.RegNum << ">";
    3332           0 :     break;
    3333             :   case k_Token:
    3334             :     OS << "'" << getToken() << "'";
    3335           0 :     break;
    3336             :   case k_VectorIndex:
    3337             :     OS << "<vectorindex " << getVectorIndex() << ">";
    3338             :     break;
    3339           0 :   }
    3340           0 : }
    3341           0 : 
    3342             : /// @name Auto-generated Match Functions
    3343             : /// {
    3344           0 : 
    3345           0 : static unsigned MatchRegisterName(StringRef Name);
    3346             : 
    3347           0 : /// }
    3348           0 : 
    3349           0 : bool ARMAsmParser::ParseRegister(unsigned &RegNo,
    3350           0 :                                  SMLoc &StartLoc, SMLoc &EndLoc) {
    3351           0 :   const AsmToken &Tok = getParser().getTok();
    3352           0 :   StartLoc = Tok.getLoc();
    3353           0 :   EndLoc = Tok.getEndLoc();
    3354           0 :   RegNo = tryParseRegister();
    3355           0 : 
    3356           0 :   return (RegNo == (unsigned)-1);
    3357           0 : }
    3358           0 : 
    3359           0 : /// Try to parse a register name.  The token must be an Identifier when called,
    3360           0 : /// and if it is a register name the token is eaten and the register number is
    3361           0 : /// returned.  Otherwise return -1.
    3362           0 : int ARMAsmParser::tryParseRegister() {
    3363           0 :   MCAsmParser &Parser = getParser();
    3364           0 :   const AsmToken &Tok = Parser.getTok();
    3365             :   if (Tok.isNot(AsmToken::Identifier)) return -1;
    3366           0 : 
    3367             :   std::string lowerCase = Tok.getString().lower();
    3368             :   unsigned RegNum = MatchRegisterName(lowerCase);
    3369             :   if (!RegNum) {
    3370             :     RegNum = StringSwitch<unsigned>(lowerCase)
    3371             :       .Case("r13", ARM::SP)
    3372             :       .Case("r14", ARM::LR)
    3373             :       .Case("r15", ARM::PC)
    3374             :       .Case("ip", ARM::R12)
    3375          45 :       // Additional register name aliases for 'gas' compatibility.
    3376             :       .Case("a1", ARM::R0)
    3377          45 :       .Case("a2", ARM::R1)
    3378          45 :       .Case("a3", ARM::R2)
    3379          45 :       .Case("a4", ARM::R3)
    3380          45 :       .Case("v1", ARM::R4)
    3381             :       .Case("v2", ARM::R5)
    3382          45 :       .Case("v3", ARM::R6)
    3383             :       .Case("v4", ARM::R7)
    3384             :       .Case("v5", ARM::R8)
    3385             :       .Case("v6", ARM::R9)
    3386             :       .Case("v7", ARM::R10)
    3387             :       .Case("v8", ARM::R11)
    3388       52093 :       .Case("sb", ARM::R9)
    3389       52093 :       .Case("sl", ARM::R10)
    3390       52093 :       .Case("fp", ARM::R11)
    3391       52093 :       .Default(0);
    3392             :   }
    3393       52044 :   if (!RegNum) {
    3394       52044 :     // Check for aliases registered via .req. Canonicalize to lower case.
    3395       52044 :     // That's more consistent since register names are case insensitive, and
    3396        1345 :     // it's how the original entry was passed in from MC/MCParser/AsmParser.
    3397             :     StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
    3398             :     // If no match, return failure.
    3399             :     if (Entry == RegisterReqs.end())
    3400             :       return -1;
    3401             :     Parser.Lex(); // Eat identifier token.
    3402             :     return Entry->getValue();
    3403             :   }
    3404             : 
    3405             :   // Some FPUs only have 16 D registers, so D16-D31 are invalid
    3406             :   if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
    3407             :     return -1;
    3408             : 
    3409             :   Parser.Lex(); // Eat identifier token.
    3410             : 
    3411             :   return RegNum;
    3412             : }
    3413             : 
    3414             : // Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
    3415             : // If a recoverable error occurs, return 1. If an irrecoverable error
    3416             : // occurs, return -1. An irrecoverable error is one where tokens have been
    3417             : // consumed in the process of trying to parse the shifter (i.e., when it is
    3418             : // indeed a shifter operand, but malformed).
    3419       50841 : int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) {
    3420             :   MCAsmParser &Parser = getParser();
    3421             :   SMLoc S = Parser.getTok().getLoc();
    3422             :   const AsmToken &Tok = Parser.getTok();
    3423        2406 :   if (Tok.isNot(AsmToken::Identifier))
    3424             :     return -1;
    3425        2406 : 
    3426             :   std::string lowerCase = Tok.getString().lower();
    3427           5 :   ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
    3428           5 :       .Case("asl", ARM_AM::lsl)
    3429             :       .Case("lsl", ARM_AM::lsl)
    3430             :       .Case("lsr", ARM_AM::lsr)
    3431             :       .Case("asr", ARM_AM::asr)
    3432       50841 :       .Case("ror", ARM_AM::ror)
    3433             :       .Case("rrx", ARM_AM::rrx)
    3434             :       .Default(ARM_AM::no_shift);
    3435       50818 : 
    3436             :   if (ShiftTy == ARM_AM::no_shift)
    3437       50818 :     return 1;
    3438             : 
    3439             :   Parser.Lex(); // Eat the operator.
    3440             : 
    3441             :   // The source register for the shift has already been added to the
    3442             :   // operand list, so we need to pop it off and combine it into the shifted
    3443             :   // register operand instead.
    3444             :   std::unique_ptr<ARMOperand> PrevOp(
    3445        1224 :       (ARMOperand *)Operands.pop_back_val().release());
    3446        1224 :   if (!PrevOp->isReg())
    3447        1224 :     return Error(PrevOp->getStartLoc(), "shift must be of a register");
    3448        1224 :   int SrcReg = PrevOp->getReg();
    3449        1224 : 
    3450             :   SMLoc EndLoc;
    3451             :   int64_t Imm = 0;
    3452        1221 :   int ShiftReg = 0;
    3453         315 :   if (ShiftTy == ARM_AM::rrx) {
    3454             :     // RRX Doesn't have an explicit shift amount. The encoder expects
    3455             :     // the shift register to be the same as the source register. Seems odd,
    3456             :     // but OK.
    3457             :     ShiftReg = SrcReg;
    3458             :   } else {
    3459             :     // Figure out if this is shifted by a constant or a register (for non-RRX).
    3460             :     if (Parser.getTok().is(AsmToken::Hash) ||
    3461             :         Parser.getTok().is(AsmToken::Dollar)) {
    3462         906 :       Parser.Lex(); // Eat hash.
    3463         315 :       SMLoc ImmLoc = Parser.getTok().getLoc();
    3464             :       const MCExpr *ShiftExpr = nullptr;
    3465         906 :       if (getParser().parseExpression(ShiftExpr, EndLoc)) {
    3466             :         Error(ImmLoc, "invalid immediate shift value");
    3467             :         return -1;
    3468             :       }
    3469             :       // The expression must be evaluatable as an immediate.
    3470             :       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
    3471        1812 :       if (!CE) {
    3472         906 :         Error(ImmLoc, "invalid immediate shift value");
    3473           0 :         return -1;
    3474         906 :       }
    3475             :       // Range check the immediate.
    3476         906 :       // lsl, ror: 0 <= imm <= 31
    3477             :       // lsr, asr: 0 <= imm <= 32
    3478             :       Imm = CE->getValue();
    3479         906 :       if (Imm < 0 ||
    3480             :           ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
    3481             :           ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
    3482             :         Error(ImmLoc, "immediate shift value out of range");
    3483             :         return -1;
    3484             :       }
    3485             :       // shift by zero is a nop. Always send it through as lsl.
    3486         856 :       // ('as' compatibility)
    3487         247 :       if (Imm == 0)
    3488         609 :         ShiftTy = ARM_AM::lsl;
    3489         609 :     } else if (Parser.getTok().is(AsmToken::Identifier)) {
    3490         609 :       SMLoc L = Parser.getTok().getLoc();
    3491         609 :       EndLoc = Parser.getTok().getEndLoc();
    3492           0 :       ShiftReg = tryParseRegister();
    3493          18 :       if (ShiftReg == -1) {
    3494             :         Error(L, "expected immediate or register in shift operand");
    3495             :         return -1;
    3496         609 :       }
    3497             :     } else {
    3498           2 :       Error(Parser.getTok().getLoc(),
    3499           2 :             "expected immediate or register in shift operand");
    3500             :       return -1;
    3501             :     }
    3502             :   }
    3503             : 
    3504         607 :   if (ShiftReg && ShiftTy != ARM_AM::rrx)
    3505         607 :     Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
    3506         599 :                                                          ShiftReg, Imm,
    3507         595 :                                                          S, EndLoc));
    3508          16 :   else
    3509          16 :     Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
    3510             :                                                           S, EndLoc));
    3511             : 
    3512             :   return 0;
    3513         591 : }
    3514             : 
    3515         247 : /// Try to parse a register name.  The token must be an Identifier when called.
    3516         247 : /// If it's a register, an AsmOperand is created. Another AsmOperand is created
    3517         247 : /// if there is a "writeback". 'true' if it's not a register.
    3518         247 : ///
    3519         247 : /// TODO this is likely to change to allow different register types and or to
    3520           0 : /// parse for a specific register type.
    3521           0 : bool ARMAsmParser::tryParseRegisterWithWriteBack(OperandVector &Operands) {
    3522             :   MCAsmParser &Parser = getParser();
    3523             :   SMLoc RegStartLoc = Parser.getTok().getLoc();
    3524           0 :   SMLoc RegEndLoc = Parser.getTok().getEndLoc();
    3525             :   int RegNo = tryParseRegister();
    3526           0 :   if (RegNo == -1)
    3527             :     return true;
    3528             : 
    3529             :   Operands.push_back(ARMOperand::CreateReg(RegNo, RegStartLoc, RegEndLoc));
    3530         888 : 
    3531         494 :   const AsmToken &ExclaimTok = Parser.getTok();
    3532             :   if (ExclaimTok.is(AsmToken::Exclaim)) {
    3533             :     Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
    3534             :                                                ExclaimTok.getLoc()));
    3535        1282 :     Parser.Lex(); // Eat exclaim token
    3536             :     return false;
    3537             :   }
    3538             : 
    3539             :   // Also check for an index operand. This is only legal for vector registers,
    3540             :   // but that'll get caught OK in operand matching, so we don't need to
    3541             :   // explicitly filter everything else out here.
    3542             :   if (Parser.getTok().is(AsmToken::LBrac)) {
    3543             :     SMLoc SIdx = Parser.getTok().getLoc();
    3544             :     Parser.Lex(); // Eat left bracket token.
    3545             : 
    3546             :     const MCExpr *ImmVal;
    3547       35888 :     if (getParser().parseExpression(ImmVal))
    3548       35888 :       return true;
    3549       35888 :     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
    3550       35888 :     if (!MCE)
    3551       35888 :       return TokError("immediate value expected for vector index");
    3552       35888 : 
    3553             :     if (Parser.getTok().isNot(AsmToken::RBrac))
    3554             :       return Error(Parser.getTok().getLoc(), "']' expected");
    3555       69334 : 
    3556             :     SMLoc E = Parser.getTok().getEndLoc();
    3557       34667 :     Parser.Lex(); // Eat right bracket token.
    3558       34667 : 
    3559         638 :     Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
    3560             :                                                      SIdx, E,
    3561         319 :                                                      getContext()));
    3562         319 :   }
    3563             : 
    3564             :   return false;
    3565             : }
    3566             : 
    3567             : /// MatchCoprocessorOperandName - Try to parse an coprocessor related
    3568       34348 : /// instruction with a symbolic operand name.
    3569         452 : /// We accept "crN" syntax for GAS compatibility.
    3570         452 : /// <operand-name> ::= <prefix><number>
    3571             : /// If CoprocOp is 'c', then:
    3572             : ///   <prefix> ::= c | cr
    3573         452 : /// If CoprocOp is 'p', then :
    3574           3 : ///   <prefix> ::= p
    3575         452 : /// <number> ::= integer in range [0, 15]
    3576             : static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
    3577           3 :   // Use the same layout as the tablegen'erated register name matcher. Ugly,
    3578             :   // but efficient.
    3579         449 :   if (Name.size() < 2 || Name[0] != CoprocOp)
    3580           0 :     return -1;
    3581             :   Name = (Name[1] == 'r') ? Name.drop_front(2) : Name.drop_front();
    3582         449 : 
    3583         449 :   switch (Name.size()) {
    3584             :   default: return -1;
    3585         898 :   case 1:
    3586             :     switch (Name[0]) {
    3587             :     default:  return -1;
    3588             :     case '0': return 0;
    3589             :     case '1': return 1;
    3590             :     case '2': return 2;
    3591             :     case '3': return 3;
    3592             :     case '4': return 4;
    3593             :     case '5': return 5;
    3594             :     case '6': return 6;
    3595             :     case '7': return 7;
    3596             :     case '8': return 8;
    3597             :     case '9': return 9;
    3598             :     }
    3599             :   case 2:
    3600             :     if (Name[0] != '1')
    3601             :       return -1;
    3602        1913 :     switch (Name[1]) {
    3603             :     default:  return -1;
    3604             :     // CP10 and CP11 are VFP/NEON and so vector instructions should be used.
    3605        1913 :     // However, old cores (v5/v6) did use them in that way.
    3606             :     case '0': return 10;
    3607        3826 :     case '1': return 11;
    3608             :     case '2': return 12;
    3609        1913 :     case '3': return 13;
    3610             :     case '4': return 14;
    3611        1679 :     case '5': return 15;
    3612        3358 :     }
    3613             :   }
    3614             : }
    3615             : 
    3616             : /// parseITCondCode - Try to parse a condition code for an IT instruction.
    3617             : OperandMatchResultTy
    3618             : ARMAsmParser::parseITCondCode(OperandVector &Operands) {
    3619             :   MCAsmParser &Parser = getParser();
    3620             :   SMLoc S = Parser.getTok().getLoc();
    3621             :   const AsmToken &Tok = Parser.getTok();
    3622             :   if (!Tok.is(AsmToken::Identifier))
    3623             :     return MatchOperand_NoMatch;
    3624             :   unsigned CC = ARMCondCodeFromString(Tok.getString());
    3625         234 :   if (CC == ~0U)
    3626         468 :     return MatchOperand_NoMatch;
    3627             :   Parser.Lex(); // Eat the token.
    3628         234 : 
    3629             :   Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
    3630             : 
    3631             :   return MatchOperand_Success;
    3632             : }
    3633             : 
    3634             : /// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
    3635             : /// token must be an Identifier when called, and if it is a coprocessor
    3636             : /// number, the token is eaten and the operand is added to the operand list.
    3637             : OperandMatchResultTy
    3638             : ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
    3639             :   MCAsmParser &Parser = getParser();
    3640             :   SMLoc S = Parser.getTok().getLoc();
    3641             :   const AsmToken &Tok = Parser.getTok();
    3642             :   if (Tok.isNot(AsmToken::Identifier))
    3643             :     return MatchOperand_NoMatch;
    3644        2784 : 
    3645        2784 :   int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
    3646        2784 :   if (Num == -1)
    3647        2784 :     return MatchOperand_NoMatch;
    3648        2784 :   // ARMv7 and v8 don't allow cp10/cp11 due to VFP/NEON specific instructions
    3649             :   if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11))
    3650        2784 :     return MatchOperand_NoMatch;
    3651        2784 : 
    3652             :   Parser.Lex(); // Eat identifier token.
    3653        2784 :   Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
    3654             :   return MatchOperand_Success;
    3655        5568 : }
    3656             : 
    3657        2784 : /// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
    3658             : /// token must be an Identifier when called, and if it is a coprocessor
    3659             : /// number, the token is eaten and the operand is added to the operand list.
    3660             : OperandMatchResultTy
    3661             : ARMAsmParser::parseCoprocRegOperand(OperandVector &Operands) {
    3662             :   MCAsmParser &Parser = getParser();
    3663             :   SMLoc S = Parser.getTok().getLoc();
    3664         892 :   const AsmToken &Tok = Parser.getTok();
    3665         892 :   if (Tok.isNot(AsmToken::Identifier))
    3666         892 :     return MatchOperand_NoMatch;
    3667         892 : 
    3668         892 :   int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
    3669             :   if (Reg == -1)
    3670             :     return MatchOperand_NoMatch;
    3671         892 : 
    3672         892 :   Parser.Lex(); // Eat identifier token.
    3673             :   Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
    3674             :   return MatchOperand_Success;
    3675         903 : }
    3676             : 
    3677             : /// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
    3678         886 : /// coproc_option : '{' imm0_255 '}'
    3679        1772 : OperandMatchResultTy
    3680         886 : ARMAsmParser::parseCoprocOptionOperand(OperandVector &Operands) {
    3681             :   MCAsmParser &Parser = getParser();
    3682             :   SMLoc S = Parser.getTok().getLoc();
    3683             : 
    3684             :   // If this isn't a '{', this isn't a coprocessor immediate operand.
    3685             :   if (Parser.getTok().isNot(AsmToken::LCurly))
    3686             :     return MatchOperand_NoMatch;
    3687        1021 :   Parser.Lex(); // Eat the '{'
    3688        1021 : 
    3689        1021 :   const MCExpr *Expr;
    3690        1021 :   SMLoc Loc = Parser.getTok().getLoc();
    3691        1021 :   if (getParser().parseExpression(Expr)) {
    3692             :     Error(Loc, "illegal expression");
    3693             :     return MatchOperand_ParseFail;
    3694        1021 :   }
    3695        1021 :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
    3696             :   if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
    3697             :     Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
    3698        1021 :     return MatchOperand_ParseFail;
    3699        2042 :   }
    3700        1021 :   int Val = CE->getValue();
    3701             : 
    3702             :   // Check for and consume the closing '}'
    3703             :   if (Parser.getTok().isNot(AsmToken::RCurly))
    3704             :     return MatchOperand_ParseFail;
    3705             :   SMLoc E = Parser.getTok().getEndLoc();
    3706         288 :   Parser.Lex(); // Eat the '}'
    3707         288 : 
    3708         288 :   Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
    3709             :   return MatchOperand_Success;
    3710             : }
    3711         288 : 
    3712             : // For register list parsing, we need to map from raw GPR register numbering
    3713          80 : // to the enumeration values. The enumeration values aren't sorted by
    3714             : // register number due to our using "sp", "lr" and "pc" as canonical names.
    3715             : static unsigned getNextRegister(unsigned Reg) {
    3716          80 :   // If this is a GPR, we need to do it manually, otherwise we can rely
    3717          80 :   // on the sort ordering of the enumeration since the other reg-classes
    3718           0 :   // are sane.
    3719           0 :   if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
    3720             :     return Reg + 1;
    3721          80 :   switch(Reg) {
    3722          80 :   default: llvm_unreachable("Invalid GPR number!");
    3723           2 :   case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
    3724           2 :   case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
    3725             :   case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
    3726             :   case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
    3727             :   case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
    3728             :   case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
    3729          78 :   case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
    3730             :   case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
    3731          78 :   }
    3732          78 : }
    3733             : 
    3734         156 : /// Parse a register list.
    3735          78 : bool ARMAsmParser::parseRegisterList(OperandVector &Operands) {
    3736             :   MCAsmParser &Parser = getParser();
    3737             :   if (Parser.getTok().isNot(AsmToken::LCurly))
    3738             :     return TokError("Token is not a Left Curly Brace");
    3739             :   SMLoc S = Parser.getTok().getLoc();
    3740             :   Parser.Lex(); // Eat '{' token.
    3741         451 :   SMLoc RegLoc = Parser.getTok().getLoc();
    3742             : 
    3743             :   // Check the first register in the list to see what register class
    3744             :   // this is a list of.
    3745         451 :   int Reg = tryParseRegister();
    3746         240 :   if (Reg == -1)
    3747         211 :     return Error(RegLoc, "register expected");
    3748           0 : 
    3749           9 :   // The reglist instructions have at most 16 registers, so reserve
    3750          66 :   // space for that many.
    3751         102 :   int EReg = 0;
    3752          10 :   SmallVector<std::pair<unsigned, unsigned>, 16> Registers;
    3753          10 : 
    3754           5 :   // Allow Q regs and just interpret them as the two D sub-registers.
    3755           0 :   if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
    3756           0 :     Reg = getDRegFromQReg(Reg);
    3757             :     EReg = MRI->getEncodingValue(Reg);
    3758             :     Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
    3759             :     ++Reg;
    3760             :   }
    3761         764 :   const MCRegisterClass *RC;
    3762         764 :   if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
    3763         764 :     RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
    3764           0 :   else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
    3765         764 :     RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
    3766         764 :   else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
    3767         764 :     RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
    3768             :   else
    3769             :     return Error(RegLoc, "invalid register in register list");
    3770             : 
    3771         764 :   // Store the register.
    3772         764 :   EReg = MRI->getEncodingValue(Reg);
    3773           3 :   Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
    3774             : 
    3775             :   // This starts immediately after the first register token in the list,
    3776             :   // so we can see either a comma or a minus (range separator) as a legal
    3777             :   // next token.
    3778             :   while (Parser.getTok().is(AsmToken::Comma) ||
    3779             :          Parser.getTok().is(AsmToken::Minus)) {
    3780             :     if (Parser.getTok().is(AsmToken::Minus)) {
    3781         761 :       Parser.Lex(); // Eat the minus.
    3782           1 :       SMLoc AfterMinusLoc = Parser.getTok().getLoc();
    3783           1 :       int EndReg = tryParseRegister();
    3784           1 :       if (EndReg == -1)
    3785           1 :         return Error(AfterMinusLoc, "register expected");
    3786             :       // Allow Q regs and just interpret them as the two D sub-registers.
    3787             :       if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
    3788         761 :         EndReg = getDRegFromQReg(EndReg) + 1;
    3789             :       // If the register is the same as the start reg, there's nothing
    3790         112 :       // more to do.
    3791             :       if (Reg == EndReg)
    3792          30 :         continue;
    3793             :       // The register must be in the same register class as the first.
    3794             :       if (!RC->contains(EndReg))
    3795           0 :         return Error(AfterMinusLoc, "invalid register in register list");
    3796             :       // Ranges must go from low to high.
    3797             :       if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
    3798         761 :         return Error(AfterMinusLoc, "bad range in register list");
    3799         761 : 
    3800             :       // Add all the registers in the range to the register list.
    3801             :       while (Reg != EndReg) {
    3802             :         Reg = getNextRegister(Reg);
    3803             :         EReg = MRI->getEncodingValue(Reg);
    3804        2019 :         Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
    3805         844 :       }
    3806        1264 :       continue;
    3807          89 :     }
    3808          89 :     Parser.Lex(); // Eat the comma.
    3809          89 :     RegLoc = Parser.getTok().getLoc();
    3810          89 :     int OldReg = Reg;
    3811           0 :     const AsmToken RegTok = Parser.getTok();
    3812             :     Reg = tryParseRegister();
    3813          89 :     if (Reg == -1)
    3814           1 :       return Error(RegLoc, "register expected");
    3815             :     // Allow Q regs and just interpret them as the two D sub-registers.
    3816             :     bool isQReg = false;
    3817          89 :     if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
    3818          89 :       Reg = getDRegFromQReg(Reg);
    3819             :       isQReg = true;
    3820          89 :     }
    3821           0 :     // The register must be in the same register class as the first.
    3822             :     if (!RC->contains(Reg))
    3823         178 :       return Error(RegLoc, "invalid register in register list");
    3824           0 :     // List must be monotonically increasing.
    3825             :     if (MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) {
    3826             :       if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
    3827         540 :         Warning(RegLoc, "register list not in ascending order");
    3828         451 :       else
    3829         451 :         return Error(RegLoc, "register list not in ascending order");
    3830         451 :     }
    3831             :     if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
    3832          89 :       Warning(RegLoc, "duplicated register (" + RegTok.getString() +
    3833             :               ") in register list");
    3834        1175 :       continue;
    3835        1175 :     }
    3836             :     // VFP register lists must also be contiguous.
    3837        1175 :     if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
    3838        1175 :         Reg != OldReg + 1)
    3839        1175 :       return Error(RegLoc, "non-contiguous register range");
    3840           0 :     EReg = MRI->getEncodingValue(Reg);
    3841             :     Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
    3842             :     if (isQReg) {
    3843        1175 :       EReg = MRI->getEncodingValue(++Reg);
    3844           0 :       Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
    3845             :     }
    3846             :   }
    3847             : 
    3848        1175 :   if (Parser.getTok().isNot(AsmToken::RCurly))
    3849           4 :     return Error(Parser.getTok().getLoc(), "'}' expected");
    3850             :   SMLoc E = Parser.getTok().getEndLoc();
    3851        3513 :   Parser.Lex(); // Eat '}' token.
    3852           3 : 
    3853           3 :   // Push the register list operand.
    3854             :   Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
    3855           0 : 
    3856             :   // The ARM system instruction variants for LDM/STM have a '^' token here.
    3857        2342 :   if (Parser.getTok().is(AsmToken::Caret)) {
    3858           0 :     Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
    3859           0 :     Parser.Lex(); // Eat '^' token.
    3860             :   }
    3861             : 
    3862             :   return false;
    3863        1171 : }
    3864         221 : 
    3865           2 : // Helper function to parse the lane index for vector lists.
    3866             : OperandMatchResultTy ARMAsmParser::
    3867        1169 : parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index, SMLoc &EndLoc) {
    3868        1169 :   MCAsmParser &Parser = getParser();
    3869           0 :   Index = 0; // Always return a defined index value.
    3870           0 :   if (Parser.getTok().is(AsmToken::LBrac)) {
    3871             :     Parser.Lex(); // Eat the '['.
    3872             :     if (Parser.getTok().is(AsmToken::RBrac)) {
    3873             :       // "Dn[]" is the 'all lanes' syntax.
    3874         755 :       LaneKind = AllLanes;
    3875           0 :       EndLoc = Parser.getTok().getEndLoc();
    3876         755 :       Parser.Lex(); // Eat the ']'.
    3877         755 :       return MatchOperand_Success;
    3878             :     }
    3879             : 
    3880        1510 :     // There's an optional '#' token here. Normally there wouldn't be, but
    3881             :     // inline assemble puts one in, and it's friendly to accept that.
    3882             :     if (Parser.getTok().is(AsmToken::Hash))
    3883         755 :       Parser.Lex(); // Eat '#' or '$'.
    3884          16 : 
    3885           8 :     const MCExpr *LaneIndex;
    3886             :     SMLoc Loc = Parser.getTok().getLoc();
    3887             :     if (getParser().parseExpression(LaneIndex)) {
    3888             :       Error(Loc, "illegal expression");
    3889             :       return MatchOperand_ParseFail;
    3890             :     }
    3891             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
    3892        7854 :     if (!CE) {
    3893             :       Error(Loc, "lane index must be empty or an integer");
    3894        7854 :       return MatchOperand_ParseFail;
    3895        7854 :     }
    3896        7854 :     if (Parser.getTok().isNot(AsmToken::RBrac)) {
    3897        3434 :       Error(Parser.getTok().getLoc(), "']' expected");
    3898        3434 :       return MatchOperand_ParseFail;
    3899             :     }
    3900        1281 :     EndLoc = Parser.getTok().getEndLoc();
    3901        1281 :     Parser.Lex(); // Eat the ']'.
    3902        1281 :     int64_t Val = CE->getValue();
    3903        1281 : 
    3904             :     // FIXME: Make this range check context sensitive for .8, .16, .32.
    3905             :     if (Val < 0 || Val > 7) {
    3906             :       Error(Parser.getTok().getLoc(), "lane index out of range");
    3907             :       return MatchOperand_ParseFail;
    3908        2153 :     }
    3909           0 :     Index = Val;
    3910             :     LaneKind = IndexedLane;
    3911             :     return MatchOperand_Success;
    3912        2153 :   }
    3913        2153 :   LaneKind = NoLanes;
    3914           0 :   return MatchOperand_Success;
    3915           0 : }
    3916             : 
    3917        2153 : // parse a vector register list
    3918             : OperandMatchResultTy
    3919           0 : ARMAsmParser::parseVectorList(OperandVector &Operands) {
    3920           0 :   MCAsmParser &Parser = getParser();
    3921             :   VectorLaneTy LaneKind;
    3922        2153 :   unsigned LaneIndex;
    3923           0 :   SMLoc S = Parser.getTok().getLoc();
    3924           0 :   // As an extension (to match gas), support a plain D register or Q register
    3925             :   // (without encosing curly braces) as a single or double entry list,
    3926        2153 :   // respectively.
    3927        2153 :   if (Parser.getTok().is(AsmToken::Identifier)) {
    3928        2153 :     SMLoc E = Parser.getTok().getEndLoc();
    3929             :     int Reg = tryParseRegister();
    3930             :     if (Reg == -1)
    3931        2153 :       return MatchOperand_NoMatch;
    3932           0 :     if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
    3933           0 :       OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
    3934             :       if (Res != MatchOperand_Success)
    3935        2153 :         return Res;
    3936        2153 :       switch (LaneKind) {
    3937        2153 :       case NoLanes:
    3938             :         Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
    3939        4420 :         break;
    3940        4420 :       case AllLanes:
    3941             :         Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
    3942             :                                                                 S, E));
    3943             :         break;
    3944             :       case IndexedLane:
    3945        2815 :         Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
    3946        2815 :                                                                LaneIndex,
    3947             :                                                                false, S, E));
    3948             :         break;
    3949        2815 :       }
    3950             :       return MatchOperand_Success;
    3951             :     }
    3952             :     if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
    3953        2815 :       Reg = getDRegFromQReg(Reg);
    3954           4 :       OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex, E);
    3955           4 :       if (Res != MatchOperand_Success)
    3956           4 :         return Res;
    3957             :       switch (LaneKind) {
    3958           4 :       case NoLanes:
    3959           4 :         Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
    3960           4 :                                    &ARMMCRegisterClasses[ARM::DPairRegClassID]);
    3961             :         Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
    3962           4 :         break;
    3963           0 :       case AllLanes:
    3964           0 :         Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
    3965           0 :                                    &ARMMCRegisterClasses[ARM::DPairRegClassID]);
    3966           0 :         Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
    3967           0 :                                                                 S, E));
    3968             :         break;
    3969           0 :       case IndexedLane:
    3970           4 :         Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
    3971           8 :                                                                LaneIndex,
    3972             :                                                                false, S, E));
    3973             :         break;
    3974           4 :       }
    3975             :       return MatchOperand_Success;
    3976           4 :     }
    3977             :     Error(S, "vector register expected");
    3978           0 :     return MatchOperand_ParseFail;
    3979           0 :   }
    3980           0 : 
    3981           0 :   if (Parser.getTok().isNot(AsmToken::LCurly))
    3982             :     return MatchOperand_NoMatch;
    3983           0 : 
    3984           0 :   Parser.Lex(); // Eat '{' token.
    3985           0 :   SMLoc RegLoc = Parser.getTok().getLoc();
    3986             : 
    3987           0 :   int Reg = tryParseRegister();
    3988           0 :   if (Reg == -1) {
    3989           0 :     Error(RegLoc, "register expected");
    3990           0 :     return MatchOperand_ParseFail;
    3991             :   }
    3992           0 :   unsigned Count = 1;
    3993             :   int Spacing = 0;
    3994           0 :   unsigned FirstReg = Reg;
    3995           0 :   // The list is of D registers, but we also allow Q regs and just interpret
    3996           0 :   // them as the two D sub-registers.
    3997             :   if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
    3998             :     FirstReg = Reg = getDRegFromQReg(Reg);
    3999           0 :     Spacing = 1; // double-spacing requires explicit D registers, otherwise
    4000             :                  // it's ambiguous with four-register single spaced.
    4001           0 :     ++Reg;
    4002             :     ++Count;
    4003           0 :   }
    4004           0 : 
    4005             :   SMLoc E;
    4006             :   if (parseVectorLane(LaneKind, LaneIndex, E) != MatchOperand_Success)
    4007        2811 :     return MatchOperand_ParseFail;
    4008             : 
    4009             :   while (Parser.getTok().is(AsmToken::Comma) ||
    4010        2811 :          Parser.getTok().is(AsmToken::Minus)) {
    4011        2811 :     if (Parser.getTok().is(AsmToken::Minus)) {
    4012             :       if (!Spacing)
    4013        2811 :         Spacing = 1; // Register range implies a single spaced list.
    4014        2811 :       else if (Spacing == 2) {
    4015           0 :         Error(Parser.getTok().getLoc(),
    4016           0 :               "sequential registers in double spaced list");
    4017             :         return MatchOperand_ParseFail;
    4018             :       }
    4019             :       Parser.Lex(); // Eat the minus.
    4020        2811 :       SMLoc AfterMinusLoc = Parser.getTok().getLoc();
    4021             :       int EndReg = tryParseRegister();
    4022             :       if (EndReg == -1) {
    4023        2811 :         Error(AfterMinusLoc, "register expected");
    4024          17 :         return MatchOperand_ParseFail;
    4025             :       }
    4026             :       // Allow Q regs and just interpret them as the two D sub-registers.
    4027          17 :       if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
    4028             :         EndReg = getDRegFromQReg(EndReg) + 1;
    4029             :       // If the register is the same as the start reg, there's nothing
    4030             :       // more to do.
    4031        2811 :       if (Reg == EndReg)
    4032        2811 :         continue;
    4033             :       // The register must be in the same register class as the first.
    4034             :       if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
    4035        7850 :         Error(AfterMinusLoc, "invalid register in register list");
    4036        2815 :         return MatchOperand_ParseFail;
    4037        5039 :       }
    4038           4 :       // Ranges must go from low to high.
    4039             :       if (Reg > EndReg) {
    4040           0 :         Error(AfterMinusLoc, "bad range in register list");
    4041           0 :         return MatchOperand_ParseFail;
    4042             :       }
    4043           0 :       // Parse the lane specifier if present.
    4044             :       VectorLaneTy NextLaneKind;
    4045           4 :       unsigned NextLaneIndex;
    4046           4 :       if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
    4047           4 :           MatchOperand_Success)
    4048           4 :         return MatchOperand_ParseFail;
    4049           0 :       if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
    4050           0 :         Error(AfterMinusLoc, "mismatched lane index in register list");
    4051             :         return MatchOperand_ParseFail;
    4052             :       }
    4053           4 : 
    4054           0 :       // Add all the registers in the range to the register list.
    4055             :       Count += EndReg - Reg;
    4056             :       Reg = EndReg;
    4057           4 :       continue;
    4058           4 :     }
    4059             :     Parser.Lex(); // Eat the comma.
    4060           4 :     RegLoc = Parser.getTok().getLoc();
    4061           0 :     int OldReg = Reg;
    4062           0 :     Reg = tryParseRegister();
    4063             :     if (Reg == -1) {
    4064             :       Error(RegLoc, "register expected");
    4065           4 :       return MatchOperand_ParseFail;
    4066           0 :     }
    4067           0 :     // vector register lists must be contiguous.
    4068             :     // It's OK to use the enumeration values directly here rather, as the
    4069             :     // VFP register classes have the enum sorted properly.
    4070             :     //
    4071             :     // The list is of D registers, but we also allow Q regs and just interpret
    4072           4 :     // them as the two D sub-registers.
    4073             :     if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
    4074             :       if (!Spacing)
    4075           4 :         Spacing = 1; // Register range implies a single spaced list.
    4076           0 :       else if (Spacing == 2) {
    4077           0 :         Error(RegLoc,
    4078             :               "invalid register in double-spaced list (must be 'D' register')");
    4079             :         return MatchOperand_ParseFail;
    4080             :       }
    4081           4 :       Reg = getDRegFromQReg(Reg);
    4082             :       if (Reg != OldReg + 1) {
    4083           4 :         Error(RegLoc, "non-contiguous register range");
    4084             :         return MatchOperand_ParseFail;
    4085        5035 :       }
    4086        5035 :       ++Reg;
    4087             :       Count += 2;
    4088        5035 :       // Parse the lane specifier if present.
    4089        5035 :       VectorLaneTy NextLaneKind;
    4090           0 :       unsigned NextLaneIndex;
    4091           0 :       SMLoc LaneLoc = Parser.getTok().getLoc();
    4092             :       if (parseVectorLane(NextLaneKind, NextLaneIndex, E) !=
    4093             :           MatchOperand_Success)
    4094             :         return MatchOperand_ParseFail;
    4095             :       if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
    4096             :         Error(LaneLoc, "mismatched lane index in register list");
    4097             :         return MatchOperand_ParseFail;
    4098             :       }
    4099        5035 :       continue;
    4100           5 :     }
    4101             :     // Normal D register.
    4102           5 :     // Figure out the register spacing (single or double) of the list if
    4103           0 :     // we don't know it already.
    4104             :     if (!Spacing)
    4105           0 :       Spacing = 1 + (Reg == OldReg + 2);
    4106             : 
    4107           5 :     // Just check that it's contiguous and keep going.
    4108           5 :     if (Reg != OldReg + Spacing) {
    4109           0 :       Error(RegLoc, "non-contiguous register range");
    4110           0 :       return MatchOperand_ParseFail;
    4111             :     }
    4112           5 :     ++Count;
    4113           5 :     // Parse the lane specifier if present.
    4114             :     VectorLaneTy NextLaneKind;
    4115             :     unsigned NextLaneIndex;
    4116             :     SMLoc EndLoc = Parser.getTok().getLoc();
    4117           5 :     if (parseVectorLane(NextLaneKind, NextLaneIndex, E) != MatchOperand_Success)
    4118           5 :       return MatchOperand_ParseFail;
    4119             :     if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
    4120             :       Error(EndLoc, "mismatched lane index in register list");
    4121           5 :       return MatchOperand_ParseFail;
    4122           0 :     }
    4123           0 :   }
    4124             : 
    4125           5 :   if (Parser.getTok().isNot(AsmToken::RCurly)) {
    4126             :     Error(Parser.getTok().getLoc(), "'}' expected");
    4127             :     return MatchOperand_ParseFail;
    4128             :   }
    4129             :   E = Parser.getTok().getEndLoc();
    4130        5030 :   Parser.Lex(); // Eat '}' token.
    4131        2420 : 
    4132             :   switch (LaneKind) {
    4133             :   case NoLanes:
    4134        5030 :     // Two-register operands have been converted to the
    4135           0 :     // composite register classes.
    4136           0 :     if (Count == 2) {
    4137             :       const MCRegisterClass *RC = (Spacing == 1) ?
    4138        5030 :         &ARMMCRegisterClasses[ARM::DPairRegClassID] :
    4139             :         &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
    4140             :       FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
    4141             :     }
    4142        5030 :     Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
    4143        5030 :                                                     (Spacing == 2), S, E));
    4144             :     break;
    4145        5030 :   case AllLanes:
    4146           0 :     // Two-register operands have been converted to the
    4147           0 :     // composite register classes.
    4148             :     if (Count == 2) {
    4149             :       const MCRegisterClass *RC = (Spacing == 1) ?
    4150             :         &ARMMCRegisterClasses[ARM::DPairRegClassID] :
    4151        2811 :         &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
    4152           0 :       FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
    4153           0 :     }
    4154             :     Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
    4155        2811 :                                                             (Spacing == 2),
    4156        2811 :                                                             S, E));
    4157             :     break;
    4158        2811 :   case IndexedLane:
    4159        1549 :     Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
    4160             :                                                            LaneIndex,
    4161             :                                                            (Spacing == 2),
    4162        1549 :                                                            S, E));
    4163         388 :     break;
    4164             :   }
    4165             :   return MatchOperand_Success;
    4166         388 : }
    4167             : 
    4168        3098 : /// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
    4169             : OperandMatchResultTy
    4170        1549 : ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
    4171         480 :   MCAsmParser &Parser = getParser();
    4172             :   SMLoc S = Parser.getTok().getLoc();
    4173             :   const AsmToken &Tok = Parser.getTok();
    4174         480 :   unsigned Opt;
    4175         171 : 
    4176             :   if (Tok.is(AsmToken::Identifier)) {
    4177             :     StringRef OptStr = Tok.getString();
    4178         171 : 
    4179             :     Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower())
    4180         960 :       .Case("sy",    ARM_MB::SY)
    4181             :       .Case("st",    ARM_MB::ST)
    4182             :       .Case("ld",    ARM_MB::LD)
    4183         480 :       .Case("sh",    ARM_MB::ISH)
    4184         782 :       .Case("ish",   ARM_MB::ISH)
    4185        1564 :       .Case("shst",  ARM_MB::ISHST)
    4186             :       .Case("ishst", ARM_MB::ISHST)
    4187             :       .Case("ishld", ARM_MB::ISHLD)
    4188             :       .Case("nsh",   ARM_MB::NSH)
    4189         782 :       .Case("un",    ARM_MB::NSH)
    4190             :       .Case("nshst", ARM_MB::NSHST)
    4191             :       .Case("nshld", ARM_MB::NSHLD)
    4192             :       .Case("unst",  ARM_MB::NSHST)
    4193             :       .Case("osh",   ARM_MB::OSH)
    4194             :       .Case("oshst", ARM_MB::OSHST)
    4195             :       .Case("oshld", ARM_MB::OSHLD)
    4196         280 :       .Default(~0U);
    4197         280 : 
    4198         280 :     // ishld, oshld, nshld and ld are only available from ARMv8.
    4199         280 :     if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD ||
    4200             :                         Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD))
    4201             :       Opt = ~0U;
    4202         280 : 
    4203         140 :     if (Opt == ~0U)
    4204             :       return MatchOperand_NoMatch;
    4205         280 : 
    4206             :     Parser.Lex(); // Eat identifier token.
    4207             :   } else if (Tok.is(AsmToken::Hash) ||
    4208             :              Tok.is(AsmToken::Dollar) ||
    4209             :              Tok.is(AsmToken::Integer)) {
    4210             :     if (Parser.getTok().isNot(AsmToken::Integer))
    4211             :       Parser.Lex(); // Eat '#' or '$'.
    4212             :     SMLoc Loc = Parser.getTok().getLoc();
    4213             : 
    4214             :     const MCExpr *MemBarrierID;
    4215             :     if (getParser().parseExpression(MemBarrierID)) {
    4216             :       Error(Loc, "illegal expression");
    4217             :       return MatchOperand_ParseFail;
    4218             :     }
    4219             : 
    4220             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
    4221             :     if (!CE) {
    4222             :       Error(Loc, "constant expression expected");
    4223             :       return MatchOperand_ParseFail;
    4224             :     }
    4225         140 : 
    4226         116 :     int Val = CE->getValue();
    4227             :     if (Val & ~0xf) {
    4228             :       Error(Loc, "immediate value out of range");
    4229         124 :       return MatchOperand_ParseFail;
    4230          20 :     }
    4231             : 
    4232         120 :     Opt = ARM_MB::RESERVED_0 + Val;
    4233           4 :   } else
    4234         144 :     return MatchOperand_ParseFail;
    4235             : 
    4236         140 :   Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
    4237         136 :   return MatchOperand_Success;
    4238         140 : }
    4239             : 
    4240             : OperandMatchResultTy
    4241         140 : ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
    4242           0 :   MCAsmParser &Parser = getParser();
    4243           4 :   SMLoc S = Parser.getTok().getLoc();
    4244             :   const AsmToken &Tok = Parser.getTok();
    4245             : 
    4246         140 :   if (Tok.isNot(AsmToken::Identifier))
    4247             :      return MatchOperand_NoMatch;
    4248           0 : 
    4249           0 :   if (!Tok.getString().equals_lower("csync"))
    4250             :     return MatchOperand_NoMatch;
    4251             : 
    4252         140 :   Parser.Lex(); // Eat identifier token.
    4253         140 : 
    4254           4 :   Operands.push_back(ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S));
    4255           4 :   return MatchOperand_Success;
    4256             : }
    4257             : 
    4258         136 : /// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
    4259             : OperandMatchResultTy
    4260             : ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
    4261             :   MCAsmParser &Parser = getParser();
    4262         512 :   SMLoc S = Parser.getTok().getLoc();
    4263         256 :   const AsmToken &Tok = Parser.getTok();
    4264             :   unsigned Opt;
    4265             : 
    4266             :   if (Tok.is(AsmToken::Identifier)) {
    4267           8 :     StringRef OptStr = Tok.getString();
    4268           8 : 
    4269           8 :     if (OptStr.equals_lower("sy"))
    4270           8 :       Opt = ARM_ISB::SY;
    4271             :     else
    4272           8 :       return MatchOperand_NoMatch;
    4273             : 
    4274             :     Parser.Lex(); // Eat identifier token.
    4275           4 :   } else if (Tok.is(AsmToken::Hash) ||
    4276           2 :              Tok.is(AsmToken::Dollar) ||
    4277             :              Tok.is(AsmToken::Integer)) {
    4278           2 :     if (Parser.getTok().isNot(AsmToken::Integer))
    4279             :       Parser.Lex(); // Eat '#' or '$'.
    4280           4 :     SMLoc Loc = Parser.getTok().getLoc();
    4281           2 : 
    4282             :     const MCExpr *ISBarrierID;
    4283             :     if (getParser().parseExpression(ISBarrierID)) {
    4284             :       Error(Loc, "illegal expression");
    4285             :       return MatchOperand_ParseFail;
    4286          30 :     }
    4287          30 : 
    4288          30 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ISBarrierID);
    4289          30 :     if (!CE) {
    4290             :       Error(Loc, "constant expression expected");
    4291             :       return MatchOperand_ParseFail;
    4292          30 :     }
    4293          11 : 
    4294             :     int Val = CE->getValue();
    4295           2 :     if (Val & ~0xf) {
    4296             :       Error(Loc, "immediate value out of range");
    4297             :       return MatchOperand_ParseFail;
    4298           2 :     }
    4299             : 
    4300           9 :     Opt = ARM_ISB::RESERVED_0 + Val;
    4301           0 :   } else
    4302          19 :     return MatchOperand_ParseFail;
    4303             : 
    4304          19 :   Operands.push_back(ARMOperand::CreateInstSyncBarrierOpt(
    4305          19 :           (ARM_ISB::InstSyncBOpt)Opt, S));
    4306          19 :   return MatchOperand_Success;
    4307             : }
    4308             : 
    4309          19 : 
    4310           0 : /// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
    4311          10 : OperandMatchResultTy
    4312             : ARMAsmParser::parseProcIFlagsOperand(OperandVector &Operands) {
    4313             :   MCAsmParser &Parser = getParser();
    4314          19 :   SMLoc S = Parser.getTok().getLoc();
    4315             :   const AsmToken &Tok = Parser.getTok();
    4316           0 :   if (!Tok.is(AsmToken::Identifier))
    4317           0 :     return MatchOperand_NoMatch;
    4318             :   StringRef IFlagsStr = Tok.getString();
    4319             : 
    4320          19 :   // An iflags string of "none" is interpreted to mean that none of the AIF
    4321          19 :   // bits are set.  Not a terribly useful instruction, but a valid encoding.
    4322          10 :   unsigned IFlags = 0;
    4323          10 :   if (IFlagsStr != "none") {
    4324             :         for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
    4325             :       unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1).lower())
    4326           9 :         .Case("a", ARM_PROC::A)
    4327             :         .Case("i", ARM_PROC::I)
    4328             :         .Case("f", ARM_PROC::F)
    4329             :         .Default(~0U);
    4330          36 : 
    4331             :       // If some specific iflag is already set, it means that some letter is
    4332          18 :       // present more than once, this is not acceptable.
    4333             :       if (Flag == ~0U || (IFlags & Flag))
    4334             :         return MatchOperand_NoMatch;
    4335             : 
    4336             :       IFlags |= Flag;
    4337             :     }
    4338          69 :   }
    4339          69 : 
    4340          69 :   Parser.Lex(); // Eat identifier token.
    4341          69 :   Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
    4342          69 :   return MatchOperand_Success;
    4343             : }
    4344          44 : 
    4345             : /// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
    4346             : OperandMatchResultTy
    4347             : ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) {
    4348             :   MCAsmParser &Parser = getParser();
    4349             :   SMLoc S = Parser.getTok().getLoc();
    4350          94 :   const AsmToken &Tok = Parser.getTok();
    4351         159 : 
    4352             :   if (Tok.is(AsmToken::Integer)) {
    4353             :     int64_t Val = Tok.getIntVal();
    4354             :     if (Val > 255 || Val < 0) {
    4355             :       return MatchOperand_NoMatch;
    4356             :     }
    4357             :     unsigned SYSmvalue = Val & 0xFF;
    4358             :     Parser.Lex();
    4359          53 :     Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
    4360             :     return MatchOperand_Success;
    4361             :   }
    4362          53 : 
    4363             :   if (!Tok.is(AsmToken::Identifier))
    4364             :     return MatchOperand_NoMatch;
    4365             :   StringRef Mask = Tok.getString();
    4366          44 : 
    4367          88 :   if (isMClass()) {
    4368          44 :     auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower());
    4369             :     if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits()))
    4370             :       return MatchOperand_NoMatch;
    4371             : 
    4372             :     unsigned SYSmvalue = TheReg->Encoding & 0xFFF;
    4373         249 : 
    4374         249 :     Parser.Lex(); // Eat identifier token.
    4375         249 :     Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S));
    4376         249 :     return MatchOperand_Success;
    4377             :   }
    4378         249 : 
    4379             :   // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
    4380           6 :   size_t Start = 0, Next = Mask.find('_');
    4381             :   StringRef Flags = "";
    4382             :   std::string SpecReg = Mask.slice(Start, Next).lower();
    4383           6 :   if (Next != StringRef::npos)
    4384           6 :     Flags = Mask.slice(Next+1, Mask.size());
    4385          12 : 
    4386           6 :   // FlagsVal contains the complete mask:
    4387             :   // 3-0: Mask
    4388             :   // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
    4389         243 :   unsigned FlagsVal = 0;
    4390             : 
    4391         239 :   if (SpecReg == "apsr") {
    4392             :     FlagsVal = StringSwitch<unsigned>(Flags)
    4393         239 :     .Case("nzcvq",  0x8) // same as CPSR_f
    4394         115 :     .Case("g",      0x4) // same as CPSR_s
    4395         230 :     .Case("nzcvqg", 0xc) // same as CPSR_fs
    4396          10 :     .Default(~0U);
    4397             : 
    4398         105 :     if (FlagsVal == ~0U) {
    4399             :       if (!Flags.empty())
    4400         105 :         return MatchOperand_NoMatch;
    4401         210 :       else
    4402         105 :         FlagsVal = 8; // No flag
    4403             :     }
    4404             :   } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
    4405             :     // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
    4406             :     if (Flags == "all" || Flags == "")
    4407             :       Flags = "fc";
    4408         124 :     for (int i = 0, e = Flags.size(); i != e; ++i) {
    4409         124 :       unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
    4410         216 :       .Case("c", 1)
    4411             :       .Case("x", 2)
    4412             :       .Case("s", 4)
    4413             :       .Case("f", 8)
    4414             :       .Default(~0U);
    4415             : 
    4416             :       // If some specific flag is already set, it means that some letter is
    4417         124 :       // present more than once, this is not acceptable.
    4418          13 :       if (Flag == ~0U || (FlagsVal & Flag))
    4419             :         return MatchOperand_NoMatch;
    4420             :       FlagsVal |= Flag;
    4421             :     }
    4422             :   } else // No match for special register.
    4423             :     return MatchOperand_NoMatch;
    4424          34 : 
    4425          13 :   // Special register without flags is NOT equivalent to "fc" flags.
    4426             :   // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
    4427             :   // two lines would enable gas compatibility at the expense of breaking
    4428             :   // round-tripping.
    4429             :   //
    4430         104 :   // if (!FlagsVal)
    4431             :   //  FlagsVal = 0x9;
    4432             : 
    4433           8 :   // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
    4434         235 :   if (SpecReg == "spsr")
    4435         345 :     FlagsVal |= 16;
    4436             : 
    4437             :   Parser.Lex(); // Eat identifier token.
    4438             :   Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
    4439             :   return MatchOperand_Success;
    4440             : }
    4441             : 
    4442             : /// parseBankedRegOperand - Try to parse a banked register (e.g. "lr_irq") for
    4443             : /// use in the MRS/MSR instructions added to support virtualization.
    4444         168 : OperandMatchResultTy
    4445           6 : ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
    4446         165 :   MCAsmParser &Parser = getParser();
    4447             :   SMLoc S = Parser.getTok().getLoc();
    4448             :   const AsmToken &Tok = Parser.getTok();
    4449             :   if (!Tok.is(AsmToken::Identifier))
    4450             :     return MatchOperand_NoMatch;
    4451             :   StringRef RegName = Tok.getString();
    4452             : 
    4453             :   auto TheReg = ARMBankedReg::lookupBankedRegByName(RegName.lower());
    4454             :   if (!TheReg)
    4455             :     return MatchOperand_NoMatch;
    4456             :   unsigned Encoding = TheReg->Encoding;
    4457             : 
    4458             :   Parser.Lex(); // Eat identifier token.
    4459             :   Operands.push_back(ARMOperand::CreateBankedReg(Encoding, S));
    4460         108 :   return MatchOperand_Success;
    4461          20 : }
    4462             : 
    4463         108 : OperandMatchResultTy
    4464         216 : ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, int Low,
    4465         108 :                           int High) {
    4466             :   MCAsmParser &Parser = getParser();
    4467             :   const AsmToken &Tok = Parser.getTok();
    4468             :   if (Tok.isNot(AsmToken::Identifier)) {
    4469             :     Error(Parser.getTok().getLoc(), Op + " operand expected.");
    4470             :     return MatchOperand_ParseFail;
    4471         136 :   }
    4472         136 :   StringRef ShiftName = Tok.getString();
    4473         136 :   std::string LowerOp = Op.lower();
    4474         136 :   std::string UpperOp = Op.upper();
    4475         136 :   if (ShiftName != LowerOp && ShiftName != UpperOp) {
    4476             :     Error(Parser.getTok().getLoc(), Op + " operand expected.");
    4477         135 :     return MatchOperand_ParseFail;
    4478             :   }
    4479         135 :   Parser.Lex(); // Eat shift type token.
    4480         135 : 
    4481             :   // There must be a '#' and a shift amount.
    4482         132 :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    4483             :       Parser.getTok().isNot(AsmToken::Dollar)) {
    4484         132 :     Error(Parser.getTok().getLoc(), "'#' expected");
    4485         264 :     return MatchOperand_ParseFail;
    4486         132 :   }
    4487             :   Parser.Lex(); // Eat hash token.
    4488             : 
    4489             :   const MCExpr *ShiftAmount;
    4490          36 :   SMLoc Loc = Parser.getTok().getLoc();
    4491             :   SMLoc EndLoc;
    4492          36 :   if (getParser().parseExpression(ShiftAmount, EndLoc)) {
    4493          36 :     Error(Loc, "illegal expression");
    4494          36 :     return MatchOperand_ParseFail;
    4495           0 :   }
    4496           0 :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
    4497             :   if (!CE) {
    4498             :     Error(Loc, "constant expression expected");
    4499          36 :     return MatchOperand_ParseFail;
    4500          36 :   }
    4501             :   int Val = CE->getValue();
    4502           4 :   if (Val < Low || Val > High) {
    4503           4 :     Error(Loc, "immediate value out of range");
    4504             :     return MatchOperand_ParseFail;
    4505          32 :   }
    4506             : 
    4507             :   Operands.push_back(ARMOperand::CreateImm(CE, Loc, EndLoc));
    4508          32 : 
    4509           0 :   return MatchOperand_Success;
    4510           0 : }
    4511           0 : 
    4512             : OperandMatchResultTy
    4513          32 : ARMAsmParser::parseSetEndImm(OperandVector &Operands) {
    4514             :   MCAsmParser &Parser = getParser();
    4515             :   const AsmToken &Tok = Parser.getTok();
    4516          32 :   SMLoc S = Tok.getLoc();
    4517          32 :   if (Tok.isNot(AsmToken::Identifier)) {
    4518          32 :     Error(S, "'be' or 'le' operand expected");
    4519           0 :     return MatchOperand_ParseFail;
    4520           0 :   }
    4521             :   int Val = StringSwitch<int>(Tok.getString().lower())
    4522          32 :     .Case("be", 1)
    4523             :     .Case("le", 0)
    4524           0 :     .Default(-1);
    4525           0 :   Parser.Lex(); // Eat the token.
    4526             : 
    4527          32 :   if (Val == -1) {
    4528          32 :     Error(S, "'be' or 'le' operand expected");
    4529           8 :     return MatchOperand_ParseFail;
    4530           8 :   }
    4531             :   Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::create(Val,
    4532             :                                                                   getContext()),
    4533          48 :                                            S, Tok.getEndLoc()));
    4534             :   return MatchOperand_Success;
    4535          24 : }
    4536             : 
    4537             : /// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
    4538             : /// instructions. Legal values are:
    4539          26 : ///     lsl #n  'n' in [0,31]
    4540          26 : ///     asr #n  'n' in [1,32]
    4541          26 : ///             n == 32 encoded as n == 0.
    4542          26 : OperandMatchResultTy
    4543          26 : ARMAsmParser::parseShifterImm(OperandVector &Operands) {
    4544           2 :   MCAsmParser &Parser = getParser();
    4545           2 :   const AsmToken &Tok = Parser.getTok();
    4546             :   SMLoc S = Tok.getLoc();
    4547          48 :   if (Tok.isNot(AsmToken::Identifier)) {
    4548             :     Error(S, "shift operator 'asr' or 'lsl' expected");
    4549             :     return MatchOperand_ParseFail;
    4550             :   }
    4551          24 :   StringRef ShiftName = Tok.getString();
    4552             :   bool isASR;
    4553          24 :   if (ShiftName == "lsl" || ShiftName == "LSL")
    4554           2 :     isASR = false;
    4555           2 :   else if (ShiftName == "asr" || ShiftName == "ASR")
    4556             :     isASR = true;
    4557          88 :   else {
    4558             :     Error(S, "shift operator 'asr' or 'lsl' expected");
    4559             :     return MatchOperand_ParseFail;
    4560          22 :   }
    4561             :   Parser.Lex(); // Eat the operator.
    4562             : 
    4563             :   // A '#' and a shift amount.
    4564             :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    4565             :       Parser.getTok().isNot(AsmToken::Dollar)) {
    4566             :     Error(Parser.getTok().getLoc(), "'#' expected");
    4567             :     return MatchOperand_ParseFail;
    4568             :   }
    4569          50 :   Parser.Lex(); // Eat hash token.
    4570          50 :   SMLoc ExLoc = Parser.getTok().getLoc();
    4571          50 : 
    4572          50 :   const MCExpr *ShiftAmount;
    4573          50 :   SMLoc EndLoc;
    4574           0 :   if (getParser().parseExpression(ShiftAmount, EndLoc)) {
    4575           0 :     Error(ExLoc, "malformed shift expression");
    4576             :     return MatchOperand_ParseFail;
    4577             :   }
    4578             :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
    4579             :   if (!CE) {
    4580             :     Error(ExLoc, "shift amount must be an immediate");
    4581             :     return MatchOperand_ParseFail;
    4582             :   }
    4583             : 
    4584           2 :   int64_t Val = CE->getValue();
    4585           2 :   if (isASR) {
    4586             :     // Shift amount must be in [1,32]
    4587          48 :     if (Val < 1 || Val > 32) {
    4588             :       Error(ExLoc, "'asr' shift amount must be in range [1,32]");
    4589             :       return MatchOperand_ParseFail;
    4590          48 :     }
    4591           2 :     // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
    4592           2 :     if (isThumb() && Val == 32) {
    4593           2 :       Error(ExLoc, "'asr #32' shift amount not allowed in Thumb mode");
    4594             :       return MatchOperand_ParseFail;
    4595          46 :     }
    4596          46 :     if (Val == 32) Val = 0;
    4597             :   } else {
    4598             :     // Shift amount must be in [1,32]
    4599          46 :     if (Val < 0 || Val > 31) {
    4600          46 :       Error(ExLoc, "'lsr' shift amount must be in range [0,31]");
    4601           0 :       return MatchOperand_ParseFail;
    4602           0 :     }
    4603             :   }
    4604          46 : 
    4605             :   Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, EndLoc));
    4606           2 : 
    4607           2 :   return MatchOperand_Success;
    4608             : }
    4609             : 
    4610          44 : /// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
    4611          44 : /// of instructions. Legal values are:
    4612             : ///     ror #n  'n' in {0, 8, 16, 24}
    4613          20 : OperandMatchResultTy
    4614           4 : ARMAsmParser::parseRotImm(OperandVector &Operands) {
    4615           4 :   MCAsmParser &Parser = getParser();
    4616             :   const AsmToken &Tok = Parser.getTok();
    4617             :   SMLoc S = Tok.getLoc();
    4618          16 :   if (Tok.isNot(AsmToken::Identifier))
    4619           4 :     return MatchOperand_NoMatch;
    4620           4 :   StringRef ShiftName = Tok.getString();
    4621             :   if (ShiftName != "ror" && ShiftName != "ROR")
    4622          12 :     return MatchOperand_NoMatch;
    4623             :   Parser.Lex(); // Eat the operator.
    4624             : 
    4625          24 :   // A '#' and a rotate amount.
    4626           4 :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    4627           4 :       Parser.getTok().isNot(AsmToken::Dollar)) {
    4628             :     Error(Parser.getTok().getLoc(), "'#' expected");
    4629             :     return MatchOperand_ParseFail;
    4630             :   }
    4631          64 :   Parser.Lex(); // Eat hash token.
    4632             :   SMLoc ExLoc = Parser.getTok().getLoc();
    4633          32 : 
    4634             :   const MCExpr *ShiftAmount;
    4635             :   SMLoc EndLoc;
    4636             :   if (getParser().parseExpression(ShiftAmount, EndLoc)) {
    4637             :     Error(ExLoc, "malformed rotate expression");
    4638             :     return MatchOperand_ParseFail;
    4639             :   }
    4640         244 :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
    4641         244 :   if (!CE) {
    4642         244 :     Error(ExLoc, "rotate amount must be an immediate");
    4643         244 :     return MatchOperand_ParseFail;
    4644         244 :   }
    4645             : 
    4646             :   int64_t Val = CE->getValue();
    4647             :   // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
    4648             :   // normally, zero is represented in asm by omitting the rotate operand
    4649         228 :   // entirely.
    4650             :   if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
    4651             :     Error(ExLoc, "'ror' rotate amount must be 8, 16, or 24");
    4652         228 :     return MatchOperand_ParseFail;
    4653           2 :   }
    4654           2 : 
    4655           2 :   Operands.push_back(ARMOperand::CreateRotImm(Val, S, EndLoc));
    4656             : 
    4657         226 :   return MatchOperand_Success;
    4658         226 : }
    4659             : 
    4660             : OperandMatchResultTy
    4661         226 : ARMAsmParser::parseModImm(OperandVector &Operands) {
    4662         226 :   MCAsmParser &Parser = getParser();
    4663           2 :   MCAsmLexer &Lexer = getLexer();
    4664           2 :   int64_t Imm1, Imm2;
    4665             : 
    4666         224 :   SMLoc S = Parser.getTok().getLoc();
    4667             : 
    4668           2 :   // 1) A mod_imm operand can appear in the place of a register name:
    4669           2 :   //   add r0, #mod_imm
    4670             :   //   add r0, r0, #mod_imm
    4671             :   // to correctly handle the latter, we bail out as soon as we see an
    4672         222 :   // identifier.
    4673             :   //
    4674             :   // 2) Similarly, we do not want to parse into complex operands:
    4675             :   //   mov r0, #mod_imm
    4676         222 :   //   mov r0, :lower16:(_foo)
    4677           4 :   if (Parser.getTok().is(AsmToken::Identifier) ||
    4678           4 :       Parser.getTok().is(AsmToken::Colon))
    4679             :     return MatchOperand_NoMatch;
    4680             : 
    4681         436 :   // Hash (dollar) is optional as per the ARMARM
    4682             :   if (Parser.getTok().is(AsmToken::Hash) ||
    4683         218 :       Parser.getTok().is(AsmToken::Dollar)) {
    4684             :     // Avoid parsing into complex operands (#:)
    4685             :     if (Lexer.peekTok().is(AsmToken::Colon))
    4686             :       return MatchOperand_NoMatch;
    4687        3539 : 
    4688        3539 :     // Eat the hash (dollar)
    4689             :     Parser.Lex();
    4690             :   }
    4691             : 
    4692        3539 :   SMLoc Sx1, Ex1;
    4693             :   Sx1 = Parser.getTok().getLoc();
    4694             :   const MCExpr *Imm1Exp;
    4695             :   if (getParser().parseExpression(Imm1Exp, Ex1)) {
    4696             :     Error(Sx1, "malformed expression");
    4697             :     return MatchOperand_ParseFail;
    4698             :   }
    4699             : 
    4700             :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm1Exp);
    4701             : 
    4702             :   if (CE) {
    4703        3539 :     // Immediate must fit within 32-bits
    4704        1260 :     Imm1 = CE->getValue();
    4705        2283 :     int Enc = ARM_AM::getSOImmVal(Imm1);
    4706             :     if (Enc != -1 && Parser.getTok().is(AsmToken::EndOfStatement)) {
    4707             :       // We have a match!
    4708        1256 :       Operands.push_back(ARMOperand::CreateModImm((Enc & 0xFF),
    4709         312 :                                                   (Enc & 0xF00) >> 7,
    4710             :                                                   Sx1, Ex1));
    4711        1908 :       return MatchOperand_Success;
    4712             :     }
    4713             : 
    4714             :     // We have parsed an immediate which is not for us, fallback to a plain
    4715        1058 :     // immediate. This can happen for instruction aliases. For an example,
    4716             :     // ARMInstrInfo.td defines the alias [mov <-> mvn] which can transform
    4717             :     // a mov (mvn) with a mod_imm_neg/mod_imm_not operand into the opposite
    4718        1254 :     // instruction with a mod_imm operand. The alias is defined such that the
    4719        1254 :     // parser method is shared, that's why we have to do this here.
    4720             :     if (Parser.getTok().is(AsmToken::EndOfStatement)) {
    4721        1254 :       Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
    4722           2 :       return MatchOperand_Success;
    4723           2 :     }
    4724             :   } else {
    4725             :     // Operands like #(l1 - l2) can only be evaluated at a later stage (via an
    4726        1252 :     // MCFixup). Fallback to a plain immediate.
    4727             :     Operands.push_back(ARMOperand::CreateImm(Imm1Exp, Sx1, Ex1));
    4728             :     return MatchOperand_Success;
    4729             :   }
    4730        1241 : 
    4731        1241 :   // From this point onward, we expect the input to be a (#bits, #rot) pair
    4732        1241 :   if (Parser.getTok().isNot(AsmToken::Comma)) {
    4733             :     Error(Sx1, "expected modified immediate operand: #[0, 255], #even[0-30]");
    4734        1574 :     return MatchOperand_ParseFail;
    4735         787 :   }
    4736             : 
    4737         787 :   if (Imm1 & ~0xFF) {
    4738             :     Error(Sx1, "immediate operand must a number in the range [0, 255]");
    4739             :     return MatchOperand_ParseFail;
    4740             :   }
    4741             : 
    4742             :   // Eat the comma
    4743             :   Parser.Lex();
    4744             : 
    4745             :   // Repeat for #rot
    4746         454 :   SMLoc Sx2, Ex2;
    4747         144 :   Sx2 = Parser.getTok().getLoc();
    4748          72 : 
    4749             :   // Eat the optional hash (dollar)
    4750             :   if (Parser.getTok().is(AsmToken::Hash) ||
    4751             :       Parser.getTok().is(AsmToken::Dollar))
    4752             :     Parser.Lex();
    4753          22 : 
    4754          11 :   const MCExpr *Imm2Exp;
    4755             :   if (getParser().parseExpression(Imm2Exp, Ex2)) {
    4756             :     Error(Sx2, "malformed expression");
    4757             :     return MatchOperand_ParseFail;
    4758         382 :   }
    4759           0 : 
    4760           0 :   CE = dyn_cast<MCConstantExpr>(Imm2Exp);
    4761             : 
    4762             :   if (CE) {
    4763         382 :     Imm2 = CE->getValue();
    4764          40 :     if (!(Imm2 & ~0x1E)) {
    4765          40 :       // We have a match!
    4766             :       Operands.push_back(ARMOperand::CreateModImm(Imm1, Imm2, S, Ex2));
    4767             :       return MatchOperand_Success;
    4768             :     }
    4769         342 :     Error(Sx2, "immediate operand must an even number in the range [0, 30]");
    4770             :     return MatchOperand_ParseFail;
    4771             :   } else {
    4772         342 :     Error(Sx2, "constant expression expected");
    4773         342 :     return MatchOperand_ParseFail;
    4774             :   }
    4775             : }
    4776         342 : 
    4777         174 : OperandMatchResultTy
    4778         226 : ARMAsmParser::parseBitfield(OperandVector &Operands) {
    4779             :   MCAsmParser &Parser = getParser();
    4780             :   SMLoc S = Parser.getTok().getLoc();
    4781         342 :   // The bitfield descriptor is really two operands, the LSB and the width.
    4782           0 :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    4783           0 :       Parser.getTok().isNot(AsmToken::Dollar)) {
    4784             :     Error(Parser.getTok().getLoc(), "'#' expected");
    4785             :     return MatchOperand_ParseFail;
    4786         342 :   }
    4787             :   Parser.Lex(); // Eat hash token.
    4788             : 
    4789         342 :   const MCExpr *LSBExpr;
    4790         342 :   SMLoc E = Parser.getTok().getLoc();
    4791             :   if (getParser().parseExpression(LSBExpr)) {
    4792         604 :     Error(E, "malformed immediate expression");
    4793         302 :     return MatchOperand_ParseFail;
    4794             :   }
    4795          40 :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
    4796          40 :   if (!CE) {
    4797             :     Error(E, "'lsb' operand must be an immediate");
    4798           0 :     return MatchOperand_ParseFail;
    4799           0 :   }
    4800             : 
    4801             :   int64_t LSB = CE->getValue();
    4802             :   // The LSB must be in the range [0,31]
    4803             :   if (LSB < 0 || LSB > 31) {
    4804          34 :     Error(E, "'lsb' operand must be in the range [0,31]");
    4805          34 :     return MatchOperand_ParseFail;
    4806          34 :   }
    4807             :   E = Parser.getTok().getLoc();
    4808          34 : 
    4809           0 :   // Expect another immediate operand.
    4810           0 :   if (Parser.getTok().isNot(AsmToken::Comma)) {
    4811           0 :     Error(Parser.getTok().getLoc(), "too few operands");
    4812             :     return MatchOperand_ParseFail;
    4813          34 :   }
    4814             :   Parser.Lex(); // Eat hash token.
    4815             :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    4816          34 :       Parser.getTok().isNot(AsmToken::Dollar)) {
    4817          34 :     Error(Parser.getTok().getLoc(), "'#' expected");
    4818           0 :     return MatchOperand_ParseFail;
    4819           0 :   }
    4820             :   Parser.Lex(); // Eat hash token.
    4821          34 : 
    4822             :   const MCExpr *WidthExpr;
    4823           0 :   SMLoc EndLoc;
    4824           0 :   if (getParser().parseExpression(WidthExpr, EndLoc)) {
    4825             :     Error(E, "malformed immediate expression");
    4826             :     return MatchOperand_ParseFail;
    4827          34 :   }
    4828             :   CE = dyn_cast<MCConstantExpr>(WidthExpr);
    4829          34 :   if (!CE) {
    4830           0 :     Error(E, "'width' operand must be an immediate");
    4831           0 :     return MatchOperand_ParseFail;
    4832             :   }
    4833          34 : 
    4834             :   int64_t Width = CE->getValue();
    4835             :   // The LSB must be in the range [1,32-lsb]
    4836          34 :   if (Width < 1 || Width > 32 - LSB) {
    4837           0 :     Error(E, "'width' operand must be in the range [1,32-lsb]");
    4838           0 :     return MatchOperand_ParseFail;
    4839             :   }
    4840          34 : 
    4841          34 :   Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, EndLoc));
    4842           0 : 
    4843           0 :   return MatchOperand_Success;
    4844           0 : }
    4845             : 
    4846          34 : OperandMatchResultTy
    4847             : ARMAsmParser::parsePostIdxReg(OperandVector &Operands) {
    4848             :   // Check for a post-index addressing register operand. Specifically:
    4849          34 :   // postidx_reg := '+' register {, shift}
    4850          34 :   //              | '-' register {, shift}
    4851           0 :   //              | register {, shift}
    4852           0 : 
    4853             :   // This method must return MatchOperand_NoMatch without consuming any tokens
    4854          34 :   // in the case where there is no match, as other alternatives take other
    4855             :   // parse methods.
    4856           0 :   MCAsmParser &Parser = getParser();
    4857           0 :   AsmToken Tok = Parser.getTok();
    4858             :   SMLoc S = Tok.getLoc();
    4859             :   bool haveEaten = false;
    4860          34 :   bool isAdd = true;
    4861             :   if (Tok.is(AsmToken::Plus)) {
    4862          34 :     Parser.Lex(); // Eat the '+' token.
    4863           0 :     haveEaten = true;
    4864           0 :   } else if (Tok.is(AsmToken::Minus)) {
    4865             :     Parser.Lex(); // Eat the '-' token.
    4866             :     isAdd = false;
    4867          68 :     haveEaten = true;
    4868             :   }
    4869          34 : 
    4870             :   SMLoc E = Parser.getTok().getEndLoc();
    4871             :   int Reg = tryParseRegister();
    4872             :   if (Reg == -1) {
    4873          99 :     if (!haveEaten)
    4874             :       return MatchOperand_NoMatch;
    4875             :     Error(Parser.getTok().getLoc(), "register expected");
    4876             :     return MatchOperand_ParseFail;
    4877             :   }
    4878             : 
    4879             :   ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
    4880             :   unsigned ShiftImm = 0;
    4881             :   if (Parser.getTok().is(AsmToken::Comma)) {
    4882          99 :     Parser.Lex(); // Eat the ','.
    4883          99 :     if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
    4884          99 :       return MatchOperand_ParseFail;
    4885             : 
    4886             :     // FIXME: Only approximates end...may include intervening whitespace.
    4887          99 :     E = Parser.getTok().getLoc();
    4888           0 :   }
    4889             : 
    4890          99 :   Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
    4891          10 :                                                   ShiftImm, S, E));
    4892             : 
    4893             :   return MatchOperand_Success;
    4894             : }
    4895             : 
    4896          99 : OperandMatchResultTy
    4897          99 : ARMAsmParser::parseAM3Offset(OperandVector &Operands) {
    4898          99 :   // Check for a post-index addressing register operand. Specifically:
    4899          43 :   // am3offset := '+' register
    4900             :   //              | '-' register
    4901           0 :   //              | register
    4902           0 :   //              | # imm
    4903             :   //              | # + imm
    4904             :   //              | # - imm
    4905          56 : 
    4906          56 :   // This method must return MatchOperand_NoMatch without consuming any tokens
    4907          56 :   // in the case where there is no match, as other alternatives take other
    4908          17 :   // parse methods.
    4909          17 :   MCAsmParser &Parser = getParser();
    4910             :   AsmToken Tok = Parser.getTok();
    4911             :   SMLoc S = Tok.getLoc();
    4912             : 
    4913          13 :   // Do immediates first, as we always parse those if we have a '#'.
    4914             :   if (Parser.getTok().is(AsmToken::Hash) ||
    4915             :       Parser.getTok().is(AsmToken::Dollar)) {
    4916         104 :     Parser.Lex(); // Eat '#' or '$'.
    4917             :     // Explicitly look for a '-', as we need to encode negative zero
    4918             :     // differently.
    4919          52 :     bool isNegative = Parser.getTok().is(AsmToken::Minus);
    4920             :     const MCExpr *Offset;
    4921             :     SMLoc E;
    4922             :     if (getParser().parseExpression(Offset, E))
    4923          53 :       return MatchOperand_ParseFail;
    4924             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
    4925             :     if (!CE) {
    4926             :       Error(S, "constant expression expected");
    4927             :       return MatchOperand_ParseFail;
    4928             :     }
    4929             :     // Negative zero is encoded as the flag value
    4930             :     // std::numeric_limits<int32_t>::min().
    4931             :     int32_t Val = CE->getValue();
    4932             :     if (isNegative && Val == 0)
    4933             :       Val = std::numeric_limits<int32_t>::min();
    4934             : 
    4935          53 :     Operands.push_back(
    4936          53 :       ARMOperand::CreateImm(MCConstantExpr::create(Val, getContext()), S, E));
    4937          53 : 
    4938             :     return MatchOperand_Success;
    4939             :   }
    4940          53 : 
    4941          24 :   bool haveEaten = false;
    4942          29 :   bool isAdd = true;
    4943             :   if (Tok.is(AsmToken::Plus)) {
    4944             :     Parser.Lex(); // Eat the '+' token.
    4945          29 :     haveEaten = true;
    4946             :   } else if (Tok.is(AsmToken::Minus)) {
    4947          29 :     Parser.Lex(); // Eat the '-' token.
    4948          29 :     isAdd = false;
    4949             :     haveEaten = true;
    4950          29 :   }
    4951             : 
    4952           0 :   Tok = Parser.getTok();
    4953           0 :   int Reg = tryParseRegister();
    4954             :   if (Reg == -1) {
    4955             :     if (!haveEaten)
    4956             :       return MatchOperand_NoMatch;
    4957          29 :     Error(Tok.getLoc(), "register expected");
    4958          29 :     return MatchOperand_ParseFail;
    4959             :   }
    4960             : 
    4961          58 :   Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
    4962          58 :                                                   0, S, Tok.getEndLoc()));
    4963             : 
    4964          29 :   return MatchOperand_Success;
    4965             : }
    4966             : 
    4967             : /// Convert parsed operands to MCInst.  Needed here because this instruction
    4968             : /// only has two register operands, but multiplication is commutative so
    4969          24 : /// assemblers should accept both "mul rD, rN, rD" and "mul rD, rD, rN".
    4970           0 : void ARMAsmParser::cvtThumbMultiply(MCInst &Inst,
    4971             :                                     const OperandVector &Operands) {
    4972          24 :   ((ARMOperand &)*Operands[3]).addRegOperands(Inst, 1);
    4973           6 :   ((ARMOperand &)*Operands[1]).addCCOutOperands(Inst, 1);
    4974             :   // If we have a three-operand form, make sure to set Rn to be the operand
    4975             :   // that isn't the same as Rd.
    4976             :   unsigned RegOp = 4;
    4977             :   if (Operands.size() == 6 &&
    4978          24 :       ((ARMOperand &)*Operands[4]).getReg() ==
    4979          24 :           ((ARMOperand &)*Operands[3]).getReg())
    4980          24 :     RegOp = 5;
    4981           0 :   ((ARMOperand &)*Operands[RegOp]).addRegOperands(Inst, 1);
    4982             :   Inst.addOperand(Inst.getOperand(0));
    4983           0 :   ((ARMOperand &)*Operands[2]).addCondCodeOperands(Inst, 2);
    4984           0 : }
    4985             : 
    4986             : void ARMAsmParser::cvtThumbBranches(MCInst &Inst,
    4987          48 :                                     const OperandVector &Operands) {
    4988             :   int CondOp = -1, ImmOp = -1;
    4989             :   switch(Inst.getOpcode()) {
    4990          24 :     case ARM::tB:
    4991             :     case ARM::tBcc:  CondOp = 1; ImmOp = 2; break;
    4992             : 
    4993             :     case ARM::t2B:
    4994             :     case ARM::t2Bcc: CondOp = 1; ImmOp = 3; break;
    4995             : 
    4996           0 :     default: llvm_unreachable("Unexpected instruction in cvtThumbBranches");
    4997             :   }
    4998           0 :   // first decide whether or not the branch should be conditional
    4999           0 :   // by looking at it's location relative to an IT block
    5000             :   if(inITBlock()) {
    5001             :     // inside an IT block we cannot have any conditional branches. any
    5002             :     // such instructions needs to be converted to unconditional form
    5003           0 :     switch(Inst.getOpcode()) {
    5004             :       case ARM::tBcc: Inst.setOpcode(ARM::tB); break;
    5005             :       case ARM::t2Bcc: Inst.setOpcode(ARM::t2B); break;
    5006             :     }
    5007           0 :   } else {
    5008             :     // outside IT blocks we can only have unconditional branches with AL
    5009           0 :     // condition code or conditional branches with non-AL condition code
    5010           0 :     unsigned Cond = static_cast<ARMOperand &>(*Operands[CondOp]).getCondCode();
    5011             :     switch(Inst.getOpcode()) {
    5012         383 :       case ARM::tB:
    5013             :       case ARM::tBcc:
    5014             :         Inst.setOpcode(Cond == ARMCC::AL ? ARM::tB : ARM::tBcc);
    5015         383 :         break;
    5016             :       case ARM::t2B:
    5017             :       case ARM::t2Bcc:
    5018             :         Inst.setOpcode(Cond == ARMCC::AL ? ARM::t2B : ARM::t2Bcc);
    5019         128 :         break;
    5020         128 :     }
    5021             :   }
    5022           0 : 
    5023             :   // now decide on encoding size based on branch target range
    5024             :   switch(Inst.getOpcode()) {
    5025             :     // classify tB as either t2B or t1B based on range of immediate operand
    5026         383 :     case ARM::tB: {
    5027             :       ARMOperand &op = static_cast<ARMOperand &>(*Operands[ImmOp]);
    5028             :       if (!op.isSignedOffset<11, 1>() && isThumb() && hasV8MBaseline())
    5029          38 :         Inst.setOpcode(ARM::t2B);
    5030             :       break;
    5031             :     }
    5032             :     // classify tBcc as either t2Bcc or t1Bcc based on range of immediate operand
    5033             :     case ARM::tBcc: {
    5034             :       ARMOperand &op = static_cast<ARMOperand &>(*Operands[ImmOp]);
    5035             :       if (!op.isSignedOffset<8, 1>() && isThumb() && hasV8MBaseline())
    5036         345 :         Inst.setOpcode(ARM::t2Bcc);
    5037         345 :       break;
    5038         236 :     }
    5039             :   }
    5040         236 :   ((ARMOperand &)*Operands[ImmOp]).addImmOperands(Inst, 1);
    5041             :   ((ARMOperand &)*Operands[CondOp]).addCondCodeOperands(Inst, 2);
    5042         109 : }
    5043             : 
    5044         109 : /// Parse an ARM memory expression, return false if successful else return true
    5045             : /// or an error.  The first token must be a '[' when called.
    5046             : bool ARMAsmParser::parseMemory(OperandVector &Operands) {
    5047             :   MCAsmParser &Parser = getParser();
    5048             :   SMLoc S, E;
    5049             :   if (Parser.getTok().isNot(AsmToken::LBrac))
    5050         383 :     return TokError("Token is not a Left Bracket");
    5051             :   S = Parser.getTok().getLoc();
    5052         130 :   Parser.Lex(); // Eat left bracket token.
    5053         130 : 
    5054         139 :   const AsmToken &BaseRegTok = Parser.getTok();
    5055             :   int BaseRegNum = tryParseRegister();
    5056             :   if (BaseRegNum == -1)
    5057             :     return Error(BaseRegTok.getLoc(), "register expected");
    5058             : 
    5059         125 :   // The next token must either be a comma, a colon or a closing bracket.
    5060         125 :   const AsmToken &Tok = Parser.getTok();
    5061         125 :   if (!Tok.is(AsmToken::Colon) && !Tok.is(AsmToken::Comma) &&
    5062             :       !Tok.is(AsmToken::RBrac))
    5063             :     return Error(Tok.getLoc(), "malformed memory operand");
    5064             : 
    5065             :   if (Tok.is(AsmToken::RBrac)) {
    5066         383 :     E = Tok.getEndLoc();
    5067         383 :     Parser.Lex(); // Eat right bracket token.
    5068         383 : 
    5069             :     Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, 0,
    5070             :                                              ARM_AM::no_shift, 0, 0, false,
    5071             :                                              S, E));
    5072        5398 : 
    5073        5398 :     // If there's a pre-indexing writeback marker, '!', just add it as a token
    5074             :     // operand. It's rather odd, but syntactically valid.
    5075        5398 :     if (Parser.getTok().is(AsmToken::Exclaim)) {
    5076           0 :       Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
    5077        5398 :       Parser.Lex(); // Eat the '!'.
    5078        5398 :     }
    5079             : 
    5080        5398 :     return false;
    5081        5398 :   }
    5082        5398 : 
    5083           0 :   assert((Tok.is(AsmToken::Colon) || Tok.is(AsmToken::Comma)) &&
    5084             :          "Lost colon or comma in memory operand?!");
    5085             :   if (Tok.is(AsmToken::Comma)) {
    5086        5398 :     Parser.Lex(); // Eat the comma.
    5087        5398 :   }
    5088             : 
    5089           0 :   // If we have a ':', it's an alignment specifier.
    5090             :   if (Parser.getTok().is(AsmToken::Colon)) {
    5091        5398 :     Parser.Lex(); // Eat the ':'.
    5092        1826 :     E = Parser.getTok().getLoc();
    5093        1826 :     SMLoc AlignmentLoc = Tok.getLoc();
    5094             : 
    5095        3652 :     const MCExpr *Expr;
    5096             :     if (getParser().parseExpression(Expr))
    5097        1826 :      return true;
    5098             : 
    5099             :     // The expression has to be a constant. Memory references with relocations
    5100             :     // don't come through here, as they use the <label> forms of the relevant
    5101        1826 :     // instructions.
    5102         440 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
    5103         220 :     if (!CE)
    5104             :       return Error (E, "constant expression expected");
    5105             : 
    5106        1826 :     unsigned Align = 0;
    5107             :     switch (CE->getValue()) {
    5108             :     default:
    5109             :       return Error(E,
    5110             :                    "alignment specifier must be 16, 32, 64, 128, or 256 bits");
    5111        3572 :     case 16:  Align = 2; break;
    5112        1446 :     case 32:  Align = 4; break;
    5113             :     case 64:  Align = 8; break;
    5114             :     case 128: Align = 16; break;
    5115             :     case 256: Align = 32; break;
    5116        3572 :     }
    5117        2130 : 
    5118        2130 :     // Now we should have the closing ']'
    5119        2130 :     if (Parser.getTok().isNot(AsmToken::RBrac))
    5120             :       return Error(Parser.getTok().getLoc(), "']' expected");
    5121             :     E = Parser.getTok().getEndLoc();
    5122        2130 :     Parser.Lex(); // Eat right bracket token.
    5123             : 
    5124             :     // Don't worry about range checking the value here. That's handled by
    5125             :     // the is*() predicates.
    5126             :     Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, 0,
    5127             :                                              ARM_AM::no_shift, 0, Align,
    5128        2130 :                                              false, S, E, AlignmentLoc));
    5129             : 
    5130           0 :     // If there's a pre-indexing writeback marker, '!', just add it as a token
    5131             :     // operand.
    5132             :     if (Parser.getTok().is(AsmToken::Exclaim)) {
    5133        2130 :       Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
    5134             :       Parser.Lex(); // Eat the '!'.
    5135           0 :     }
    5136             : 
    5137             :     return false;
    5138         410 :   }
    5139         473 : 
    5140         429 :   // If we have a '#', it's an immediate offset, else assume it's a register
    5141         417 :   // offset. Be friendly and also accept a plain integer (without a leading
    5142             :   // hash) for gas compatibility.
    5143             :   if (Parser.getTok().is(AsmToken::Hash) ||
    5144             :       Parser.getTok().is(AsmToken::Dollar) ||
    5145        2130 :       Parser.getTok().is(AsmToken::Integer)) {
    5146           0 :     if (Parser.getTok().isNot(AsmToken::Integer))
    5147        2130 :       Parser.Lex(); // Eat '#' or '$'.
    5148        2130 :     E = Parser.getTok().getLoc();
    5149             : 
    5150             :     bool isNegative = getParser().getTok().is(AsmToken::Minus);
    5151             :     const MCExpr *Offset;
    5152        4260 :     if (getParser().parseExpression(Offset))
    5153             :      return true;
    5154             : 
    5155             :     // The expression has to be a constant. Memory references with relocations
    5156             :     // don't come through here, as they use the <label> forms of the relevant
    5157             :     // instructions.
    5158        2130 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
    5159        1416 :     if (!CE)
    5160         708 :       return Error (E, "constant expression expected");
    5161             : 
    5162             :     // If the constant was #-0, represent it as
    5163        2130 :     // std::numeric_limits<int32_t>::min().
    5164             :     int32_t Val = CE->getValue();
    5165             :     if (isNegative && Val == 0)
    5166             :       CE = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
    5167             :                                   getContext());
    5168             : 
    5169        1442 :     // Now we should have the closing ']'
    5170        1442 :     if (Parser.getTok().isNot(AsmToken::RBrac))
    5171         420 :       return Error(Parser.getTok().getLoc(), "']' expected");
    5172        1022 :     E = Parser.getTok().getEndLoc();
    5173        1022 :     Parser.Lex(); // Eat right bracket token.
    5174        1022 : 
    5175             :     // Don't worry about range checking the value here. That's handled by
    5176        1022 :     // the is*() predicates.
    5177             :     Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
    5178        1022 :                                              ARM_AM::no_shift, 0, 0,
    5179             :                                              false, S, E));
    5180             : 
    5181             :     // If there's a pre-indexing writeback marker, '!', just add it as a token
    5182             :     // operand.
    5183             :     if (Parser.getTok().is(AsmToken::Exclaim)) {
    5184        1022 :       Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
    5185             :       Parser.Lex(); // Eat the '!'.
    5186           0 :     }
    5187             : 
    5188             :     return false;
    5189             :   }
    5190        1022 : 
    5191        1022 :   // The register offset is optionally preceded by a '+' or '-'
    5192         194 :   bool isNegative = false;
    5193             :   if (Parser.getTok().is(AsmToken::Minus)) {
    5194             :     isNegative = true;
    5195             :     Parser.Lex(); // Eat the '-'.
    5196        1022 :   } else if (Parser.getTok().is(AsmToken::Plus)) {
    5197           0 :     // Nothing to do.
    5198        1022 :     Parser.Lex(); // Eat the '+'.
    5199        1022 :   }
    5200             : 
    5201             :   E = Parser.getTok().getLoc();
    5202             :   int OffsetRegNum = tryParseRegister();
    5203        2044 :   if (OffsetRegNum == -1)
    5204             :     return Error(E, "register expected");
    5205        1022 : 
    5206             :   // If there's a shift operator, handle it.
    5207             :   ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
    5208             :   unsigned ShiftImm = 0;
    5209        1022 :   if (Parser.getTok().is(AsmToken::Comma)) {
    5210         636 :     Parser.Lex(); // Eat the ','.
    5211         318 :     if (parseMemRegOffsetShift(ShiftType, ShiftImm))
    5212             :       return true;
    5213             :   }
    5214        1022 : 
    5215             :   // Now we should have the closing ']'
    5216             :   if (Parser.getTok().isNot(AsmToken::RBrac))
    5217             :     return Error(Parser.getTok().getLoc(), "']' expected");
    5218             :   E = Parser.getTok().getEndLoc();
    5219         420 :   Parser.Lex(); // Eat right bracket token.
    5220             : 
    5221          19 :   Operands.push_back(ARMOperand::CreateMem(BaseRegNum, nullptr, OffsetRegNum,
    5222         401 :                                            ShiftType, ShiftImm, 0, isNegative,
    5223             :                                            S, E));
    5224           1 : 
    5225             :   // If there's a pre-indexing writeback marker, '!', just add it as a token
    5226             :   // operand.
    5227         420 :   if (Parser.getTok().is(AsmToken::Exclaim)) {
    5228         420 :     Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
    5229         420 :     Parser.Lex(); // Eat the '!'.
    5230           0 :   }
    5231             : 
    5232             :   return false;
    5233         420 : }
    5234         420 : 
    5235         420 : /// parseMemRegOffsetShift - one of these two:
    5236         136 : ///   ( lsl | lsr | asr | ror ) , # shift_amount
    5237         136 : ///   rrx
    5238             : /// return true if it parses a shift otherwise it returns false.
    5239             : bool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
    5240             :                                           unsigned &Amount) {
    5241             :   MCAsmParser &Parser = getParser();
    5242         404 :   SMLoc Loc = Parser.getTok().getLoc();
    5243           4 :   const AsmToken &Tok = Parser.getTok();
    5244         402 :   if (Tok.isNot(AsmToken::Identifier))
    5245         402 :     return Error(Loc, "illegal shift operator");
    5246             :   StringRef ShiftName = Tok.getString();
    5247         804 :   if (ShiftName == "lsl" || ShiftName == "LSL" ||
    5248             :       ShiftName == "asl" || ShiftName == "ASL")
    5249         402 :     St = ARM_AM::lsl;
    5250             :   else if (ShiftName == "lsr" || ShiftName == "LSR")
    5251             :     St = ARM_AM::lsr;
    5252             :   else if (ShiftName == "asr" || ShiftName == "ASR")
    5253         402 :     St = ARM_AM::asr;
    5254          80 :   else if (ShiftName == "ror" || ShiftName == "ROR")
    5255          40 :     St = ARM_AM::ror;
    5256             :   else if (ShiftName == "rrx" || ShiftName == "RRX")
    5257             :     St = ARM_AM::rrx;
    5258             :   else
    5259             :     return Error(Loc, "illegal shift operator");
    5260             :   Parser.Lex(); // Eat shift type token.
    5261             : 
    5262             :   // rrx stands alone.
    5263             :   Amount = 0;
    5264             :   if (St != ARM_AM::rrx) {
    5265         153 :     Loc = Parser.getTok().getLoc();
    5266             :     // A '#' and a shift amount.
    5267         153 :     const AsmToken &HashTok = Parser.getTok();
    5268         153 :     if (HashTok.isNot(AsmToken::Hash) &&
    5269         153 :         HashTok.isNot(AsmToken::Dollar))
    5270         153 :       return Error(HashTok.getLoc(), "'#' expected");
    5271           0 :     Parser.Lex(); // Eat hash token.
    5272             : 
    5273             :     const MCExpr *Expr;
    5274             :     if (getParser().parseExpression(Expr))
    5275         106 :       return true;
    5276             :     // Range check the immediate.
    5277          17 :     // lsl, ror: 0 <= imm <= 31
    5278             :     // lsr, asr: 0 <= imm <= 32
    5279          14 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
    5280             :     if (!CE)
    5281           8 :       return Error(Loc, "shift amount must be an immediate");
    5282             :     int64_t Imm = CE->getValue();
    5283           6 :     if (Imm < 0 ||
    5284             :         ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
    5285           2 :         ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
    5286         151 :       return Error(Loc, "immediate shift value out of range");
    5287             :     // If <ShiftTy> #0, turn it into a no_shift.
    5288             :     if (Imm == 0)
    5289         151 :       St = ARM_AM::lsl;
    5290         151 :     // For consistency, treat lsr #32 and asr #32 as having immediate value 0.
    5291         145 :     if (Imm == 32)
    5292             :       Imm = 0;
    5293         145 :     Amount = Imm;
    5294         145 :   }
    5295             : 
    5296           0 :   return false;
    5297         145 : }
    5298             : 
    5299             : /// parseFPImm - A floating point immediate expression operand.
    5300         145 : OperandMatchResultTy
    5301             : ARMAsmParser::parseFPImm(OperandVector &Operands) {
    5302             :   MCAsmParser &Parser = getParser();
    5303             :   // Anything that can accept a floating point constant as an operand
    5304             :   // needs to go through here, as the regular parseExpression is
    5305         145 :   // integer only.
    5306             :   //
    5307           2 :   // This routine still creates a generic Immediate operand, containing
    5308         143 :   // a bitcast of the 64-bit floating point value. The various operands
    5309         143 :   // that accept floats can check whether the value is valid for them
    5310         135 :   // via the standard is*() predicates.
    5311         131 : 
    5312          16 :   SMLoc S = Parser.getTok().getLoc();
    5313             : 
    5314         127 :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    5315          25 :       Parser.getTok().isNot(AsmToken::Dollar))
    5316             :     return MatchOperand_NoMatch;
    5317         127 : 
    5318             :   // Disambiguate the VMOV forms that can accept an FP immediate.
    5319         127 :   // vmov.f32 <sreg>, #imm
    5320             :   // vmov.f64 <dreg>, #imm
    5321             :   // vmov.f32 <dreg>, #imm  @ vector f32x2
    5322             :   // vmov.f32 <qreg>, #imm  @ vector f32x4
    5323             :   //
    5324             :   // There are also the NEON VMOV instructions which expect an
    5325             :   // integer constant. Make sure we don't try to parse an FPImm
    5326             :   // for these:
    5327         566 :   // vmov.i{8|16|32|64} <dreg|qreg>, #imm
    5328         566 :   ARMOperand &TyOp = static_cast<ARMOperand &>(*Operands[2]);
    5329             :   bool isVmovf = TyOp.isToken() &&
    5330             :                  (TyOp.getToken() == ".f32" || TyOp.getToken() == ".f64" ||
    5331             :                   TyOp.getToken() == ".f16");
    5332             :   ARMOperand &Mnemonic = static_cast<ARMOperand &>(*Operands[0]);
    5333             :   bool isFconst = Mnemonic.isToken() && (Mnemonic.getToken() == "fconstd" ||
    5334             :                                          Mnemonic.getToken() == "fconsts");
    5335             :   if (!(isVmovf || isFconst))
    5336             :     return MatchOperand_NoMatch;
    5337             : 
    5338         566 :   Parser.Lex(); // Eat '#' or '$'.
    5339             : 
    5340         566 :   // Handle negation, as that still comes through as a separate token.
    5341         245 :   bool isNegative = false;
    5342             :   if (Parser.getTok().is(AsmToken::Minus)) {
    5343             :     isNegative = true;
    5344             :     Parser.Lex();
    5345             :   }
    5346             :   const AsmToken &Tok = Parser.getTok();
    5347             :   SMLoc Loc = Tok.getLoc();
    5348             :   if (Tok.is(AsmToken::Real) && isVmovf) {
    5349             :     APFloat RealVal(APFloat::IEEEsingle(), Tok.getString());
    5350             :     uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
    5351             :     // If we had a '-' in front, toggle the sign bit.
    5352             :     IntVal ^= (uint64_t)isNegative << 31;
    5353             :     Parser.Lex(); // Eat the token.
    5354             :     Operands.push_back(ARMOperand::CreateImm(
    5355         321 :           MCConstantExpr::create(IntVal, getContext()),
    5356         311 :           S, Parser.getTok().getLoc()));
    5357             :     return MatchOperand_Success;
    5358             :   }
    5359         321 :   // Also handle plain integers. Instructions which allow floating point
    5360             :   // immediates also allow a raw encoded 8-bit value.
    5361         321 :   if (Tok.is(AsmToken::Integer) && isFconst) {
    5362             :     int64_t Val = Tok.getIntVal();
    5363             :     Parser.Lex(); // Eat the token.
    5364          45 :     if (Val > 255 || Val < 0) {
    5365             :       Error(Loc, "encoded floating point value out of range");
    5366             :       return MatchOperand_ParseFail;
    5367             :     }
    5368          45 :     float RealVal = ARM_AM::getFPImmFloat(Val);
    5369             :     Val = APFloat(RealVal).bitcastToAPInt().getZExtValue();
    5370          10 : 
    5371             :     Operands.push_back(ARMOperand::CreateImm(
    5372          45 :         MCConstantExpr::create(Val, getContext()), S,
    5373          45 :         Parser.getTok().getLoc()));
    5374          45 :     return MatchOperand_Success;
    5375          33 :   }
    5376          33 : 
    5377             :   Error(Loc, "invalid floating point immediate");
    5378          33 :   return MatchOperand_ParseFail;
    5379          33 : }
    5380          99 : 
    5381          33 : /// Parse a arm instruction operand.  For now this parses the operand regardless
    5382          33 : /// of the mnemonic.
    5383             : bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
    5384             :   MCAsmParser &Parser = getParser();
    5385             :   SMLoc S, E;
    5386             : 
    5387          12 :   // Check if the current operand has a custom associated parser, if so, try to
    5388             :   // custom parse the operand, or fallback to the general approach.
    5389           8 :   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
    5390           8 :   if (ResTy == MatchOperand_Success)
    5391           0 :     return false;
    5392           0 :   // If there wasn't a custom match, try the generic matcher below. Otherwise,
    5393             :   // there was a match, but an error occurred, in which case, just return that
    5394           8 :   // the operand parsing failed.
    5395          16 :   if (ResTy == MatchOperand_ParseFail)
    5396             :     return true;
    5397          24 : 
    5398           8 :   switch (getLexer().getKind()) {
    5399           8 :   default:
    5400           8 :     Error(Parser.getTok().getLoc(), "unexpected token in operand");
    5401             :     return true;
    5402             :   case AsmToken::Identifier: {
    5403           4 :     // If we've seen a branch mnemonic, the next operand must be a label.  This
    5404           4 :     // is true even if the label is a register name.  So "br r1" means branch to
    5405             :     // label "r1".
    5406             :     bool ExpectLabel = Mnemonic == "b" || Mnemonic == "bl";
    5407             :     if (!ExpectLabel) {
    5408             :       if (!tryParseRegisterWithWriteBack(Operands))
    5409       57970 :         return false;
    5410       57970 :       int Res = tryParseShiftRegister(Operands);
    5411             :       if (Res == 0) // success
    5412             :         return false;
    5413             :       else if (Res == -1) // irrecoverable error
    5414             :         return true;
    5415       57970 :       // If this is VMRS, check for the apsr_nzcv operand.
    5416       57970 :       if (Mnemonic == "vmrs" &&
    5417             :           Parser.getTok().getString().equals_lower("apsr_nzcv")) {
    5418             :         S = Parser.getTok().getLoc();
    5419             :         Parser.Lex();
    5420             :         Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S));
    5421       48067 :         return false;
    5422             :       }
    5423             :     }
    5424       47917 : 
    5425             :     // Fall though for the Identifier case that is not a register or a
    5426           2 :     // special name.
    5427           2 :     LLVM_FALLTHROUGH;
    5428             :   }
    5429             :   case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
    5430             :   case AsmToken::Integer: // things like 1f and 2b as a branch targets
    5431             :   case AsmToken::String:  // quoted label names.
    5432             :   case AsmToken::Dot: {   // . as a branch target
    5433             :     // This was not a register so parse other operands that start with an
    5434       35888 :     // identifier (like labels) as expressions and create them as immediates.
    5435             :     const MCExpr *IdVal;
    5436        1224 :     S = Parser.getTok().getLoc();
    5437        1224 :     if (getParser().parseExpression(IdVal))
    5438             :       return true;
    5439         336 :     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
    5440             :     Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
    5441             :     return false;
    5442             :   }
    5443         315 :   case AsmToken::LBrac:
    5444           0 :     return parseMemory(Operands);
    5445           0 :   case AsmToken::LCurly:
    5446           0 :     return parseRegisterList(Operands);
    5447           0 :   case AsmToken::Dollar:
    5448             :   case AsmToken::Hash:
    5449             :     // #42 -> immediate.
    5450             :     S = Parser.getTok().getLoc();
    5451             :     Parser.Lex();
    5452             : 
    5453             :     if (Parser.getTok().isNot(AsmToken::Colon)) {
    5454             :       bool isNegative = Parser.getTok().is(AsmToken::Minus);
    5455             :       const MCExpr *ImmVal;
    5456             :       if (getParser().parseExpression(ImmVal))
    5457             :         return true;
    5458             :       const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
    5459             :       if (CE) {
    5460             :         int32_t Val = CE->getValue();
    5461             :         if (isNegative && Val == 0)
    5462         863 :           ImmVal = MCConstantExpr::create(std::numeric_limits<int32_t>::min(),
    5463         863 :                                           getContext());
    5464             :       }
    5465         860 :       E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
    5466        1720 :       Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
    5467         860 : 
    5468             :       // There can be a trailing '!' on operands that we want as a separate
    5469        5398 :       // '!' Token operand. Handle that here. For example, the compatibility
    5470        5398 :       // alias for 'srsdb sp!, #imm' is 'srsdb #imm!'.
    5471         704 :       if (Parser.getTok().is(AsmToken::Exclaim)) {
    5472         704 :         Operands.push_back(ARMOperand::CreateToken(Parser.getTok().getString(),
    5473        4818 :                                                    Parser.getTok().getLoc()));
    5474             :         Parser.Lex(); // Eat exclaim token
    5475             :       }
    5476        4818 :       return false;
    5477        4818 :     }
    5478             :     // w/ a ':' after the '#', it's just like a plain ':'.
    5479        4818 :     LLVM_FALLTHROUGH;
    5480        4795 : 
    5481             :   case AsmToken::Colon: {
    5482        4795 :     S = Parser.getTok().getLoc();
    5483             :     // ":lower16:" and ":upper16:" expression prefixes
    5484        4795 :     // FIXME: Check it's an expression prefix,
    5485             :     // e.g. (FOO - :lower16:BAR) isn't legal.
    5486        4791 :     ARMMCExpr::VariantKind RefKind;
    5487        4791 :     if (parsePrefix(RefKind))
    5488          93 :       return true;
    5489             : 
    5490             :     const MCExpr *SubExprVal;
    5491        4795 :     if (getParser().parseExpression(SubExprVal))
    5492        9590 :       return true;
    5493             : 
    5494             :     const MCExpr *ExprVal = ARMMCExpr::create(RefKind, SubExprVal,
    5495             :                                               getContext());
    5496             :     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
    5497        4795 :     Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
    5498          56 :     return false;
    5499          28 :   }
    5500          28 :   case AsmToken::Equal: {
    5501             :     S = Parser.getTok().getLoc();
    5502        4795 :     if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
    5503          23 :       return Error(S, "unexpected token in operand");
    5504             :     Parser.Lex(); // Eat '='
    5505             :     const MCExpr *SubExprVal;
    5506             :     if (getParser().parseExpression(SubExprVal))
    5507             :       return true;
    5508         194 :     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
    5509             : 
    5510             :     // execute-only: we assume that assembly programmers know what they are
    5511             :     // doing and allow literal pool creation here
    5512             :     Operands.push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E));
    5513         194 :     return false;
    5514             :   }
    5515             :   }
    5516             : }
    5517         194 : 
    5518             : // parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
    5519             : //  :lower16: and :upper16:.
    5520         194 : bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
    5521         194 :   MCAsmParser &Parser = getParser();
    5522         194 :   RefKind = ARMMCExpr::VK_ARM_None;
    5523         388 : 
    5524         194 :   // consume an optional '#' (GNU compatibility)
    5525             :   if (getLexer().is(AsmToken::Hash))
    5526         388 :     Parser.Lex();
    5527         388 : 
    5528             :   // :lower16: and :upper16: modifiers
    5529           0 :   assert(getLexer().is(AsmToken::Colon) && "expected a :");
    5530         388 :   Parser.Lex(); // Eat ':'
    5531             : 
    5532         388 :   if (getLexer().isNot(AsmToken::Identifier)) {
    5533             :     Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
    5534         388 :     return true;
    5535             :   }
    5536             : 
    5537             :   enum {
    5538         776 :     COFF = (1 << MCObjectFileInfo::IsCOFF),
    5539         388 :     ELF = (1 << MCObjectFileInfo::IsELF),
    5540             :     MACHO = (1 << MCObjectFileInfo::IsMachO),
    5541             :     WASM = (1 << MCObjectFileInfo::IsWasm),
    5542             :   };
    5543             :   static const struct PrefixEntry {
    5544             :     const char *Spelling;
    5545             :     ARMMCExpr::VariantKind VariantKind;
    5546         194 :     uint8_t SupportedFormats;
    5547         194 :   } PrefixEntries[] = {
    5548         194 :     { "lower16", ARMMCExpr::VK_ARM_LO16, COFF | ELF | MACHO },
    5549             :     { "upper16", ARMMCExpr::VK_ARM_HI16, COFF | ELF | MACHO },
    5550             :   };
    5551         194 : 
    5552           0 :   StringRef IDVal = Parser.getTok().getIdentifier();
    5553             : 
    5554             :   const auto &Prefix =
    5555             :       std::find_if(std::begin(PrefixEntries), std::end(PrefixEntries),
    5556         194 :                    [&IDVal](const PrefixEntry &PE) {
    5557             :                       return PE.Spelling == IDVal;
    5558         194 :                    });
    5559           0 :   if (Prefix == std::end(PrefixEntries)) {
    5560           0 :     Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
    5561             :     return true;
    5562             :   }
    5563             : 
    5564             :   uint8_t CurrentFormat;
    5565             :   switch (getContext().getObjectFileInfo()->getObjectFileType()) {
    5566             :   case MCObjectFileInfo::IsMachO:
    5567             :     CurrentFormat = MACHO;
    5568             :     break;
    5569             :   case MCObjectFileInfo::IsELF:
    5570             :     CurrentFormat = ELF;
    5571             :     break;
    5572             :   case MCObjectFileInfo::IsCOFF:
    5573             :     CurrentFormat = COFF;
    5574             :     break;
    5575             :   case MCObjectFileInfo::IsWasm:
    5576             :     CurrentFormat = WASM;
    5577             :     break;
    5578         388 :   }
    5579             : 
    5580             :   if (~Prefix->SupportedFormats & CurrentFormat) {
    5581             :     Error(Parser.getTok().getLoc(),
    5582             :           "cannot represent relocation in the current file format");
    5583             :     return true;
    5584             :   }
    5585         194 : 
    5586           0 :   RefKind = Prefix->VariantKind;
    5587           0 :   Parser.Lex();
    5588             : 
    5589             :   if (getLexer().isNot(AsmToken::Colon)) {
    5590             :     Error(Parser.getTok().getLoc(), "unexpected token after prefix");
    5591         194 :     return true;
    5592             :   }
    5593             :   Parser.Lex(); // Eat the last ':'
    5594             : 
    5595             :   return false;
    5596             : }
    5597             : 
    5598             : /// Given a mnemonic, split out possible predication code and carry
    5599             : /// setting letters to form a canonical mnemonic and flags.
    5600             : //
    5601             : // FIXME: Would be nice to autogen this.
    5602             : // FIXME: This is a bit of a maze of special cases.
    5603             : StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
    5604             :                                       unsigned &PredicationCode,
    5605             :                                       bool &CarrySetting,
    5606         194 :                                       unsigned &ProcessorIMod,
    5607           0 :                                       StringRef &ITMask) {
    5608             :   PredicationCode = ARMCC::AL;
    5609           0 :   CarrySetting = false;
    5610             :   ProcessorIMod = 0;
    5611             : 
    5612         194 :   // Ignore some mnemonics we know aren't predicated forms.
    5613         194 :   //
    5614             :   // FIXME: Would be nice to autogen this.
    5615         194 :   if ((Mnemonic == "movs" && isThumb()) ||
    5616           0 :       Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
    5617           0 :       Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
    5618             :       Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
    5619         194 :       Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
    5620             :       Mnemonic == "vaclt" || Mnemonic == "vacle"  || Mnemonic == "hlt" ||
    5621         194 :       Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
    5622             :       Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
    5623             :       Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
    5624             :       Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" ||
    5625             :       Mnemonic == "vcvta" || Mnemonic == "vcvtn"  || Mnemonic == "vcvtp" ||
    5626             :       Mnemonic == "vcvtm" || Mnemonic == "vrinta" || Mnemonic == "vrintn" ||
    5627             :       Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic == "hvc" ||
    5628             :       Mnemonic.startswith("vsel") || Mnemonic == "vins" || Mnemonic == "vmovx" ||
    5629       25833 :       Mnemonic == "bxns"  || Mnemonic == "blxns" ||
    5630             :       Mnemonic == "vudot" || Mnemonic == "vsdot" ||
    5631             :       Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
    5632             :       Mnemonic == "vfmal" || Mnemonic == "vfmsl")
    5633             :     return Mnemonic;
    5634       25833 : 
    5635       25833 :   // First, split out any predication code. Ignore mnemonics we know aren't
    5636       25833 :   // predicated but do have a carry-set and so weren't caught above.
    5637             :   if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
    5638             :       Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
    5639             :       Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
    5640             :       Mnemonic != "sbcs" && Mnemonic != "rscs") {
    5641         141 :     unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2));
    5642             :     if (CC != ~0U) {
    5643             :       Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
    5644             :       PredicationCode = CC;
    5645             :     }
    5646             :   }
    5647             : 
    5648             :   // Next, determine if we have a carry setting bit. We explicitly ignore all
    5649             :   // the instructions we know end in 's'.
    5650             :   if (Mnemonic.endswith("s") &&
    5651             :       !(Mnemonic == "cps" || Mnemonic == "mls" ||
    5652             :         Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
    5653             :         Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
    5654             :         Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
    5655             :         Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
    5656             :         Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
    5657             :         Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
    5658             :         Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" ||
    5659        2296 :         Mnemonic == "vfms" || Mnemonic == "vfnms" || Mnemonic == "fconsts" ||
    5660             :         Mnemonic == "bxns" || Mnemonic == "blxns" ||
    5661             :         (Mnemonic == "movs" && isThumb()))) {
    5662             :     Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
    5663             :     CarrySetting = true;
    5664             :   }
    5665             : 
    5666             :   // The "cps" instruction can have a interrupt mode operand which is glued into
    5667       46666 :   // the mnemonic. Check if this is the case, split it and parse the imod op
    5668       23333 :   if (Mnemonic.startswith("cps")) {
    5669        3919 :     // Split out any imod code.
    5670        3919 :     unsigned IMod =
    5671             :       StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
    5672             :       .Case("ie", ARM_PROC::IE)
    5673             :       .Case("id", ARM_PROC::ID)
    5674             :       .Default(~0U);
    5675             :     if (IMod != ~0U) {
    5676             :       Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
    5677             :       ProcessorIMod = IMod;
    5678             :     }
    5679             :   }
    5680             : 
    5681             :   // The "it" instruction has the condition mask on the end of the mnemonic.
    5682             :   if (Mnemonic.startswith("it")) {
    5683             :     ITMask = Mnemonic.slice(2, Mnemonic.size());
    5684             :     Mnemonic = Mnemonic.slice(0, 2);
    5685             :   }
    5686             : 
    5687          54 :   return Mnemonic;
    5688        1526 : }
    5689        1526 : 
    5690             : /// Given a canonical mnemonic, determine if the instruction ever allows
    5691             : /// inclusion of carry set or predication code operands.
    5692             : //
    5693             : // FIXME: It would be nice to autogen this.
    5694             : void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
    5695             :                                          bool &CanAcceptCarrySet,
    5696             :                                          bool &CanAcceptPredicationCode) {
    5697         130 :   CanAcceptCarrySet =
    5698             :       Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
    5699             :       Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
    5700             :       Mnemonic == "add" || Mnemonic == "adc" || Mnemonic == "mul" ||
    5701          44 :       Mnemonic == "bic" || Mnemonic == "asr" || Mnemonic == "orr" ||
    5702          44 :       Mnemonic == "mvn" || Mnemonic == "rsb" || Mnemonic == "rsc" ||
    5703          44 :       Mnemonic == "orn" || Mnemonic == "sbc" || Mnemonic == "eor" ||
    5704             :       Mnemonic == "neg" || Mnemonic == "vfm" || Mnemonic == "vfnm" ||
    5705             :       (!isThumb() &&
    5706             :        (Mnemonic == "smull" || Mnemonic == "mov" || Mnemonic == "mla" ||
    5707             :         Mnemonic == "smlal" || Mnemonic == "umlal" || Mnemonic == "umull"));
    5708             : 
    5709        2791 :   if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
    5710        2791 :       Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
    5711             :       Mnemonic == "trap" || Mnemonic == "hlt" || Mnemonic == "udf" ||
    5712             :       Mnemonic.startswith("crc32") || Mnemonic.startswith("cps") ||
    5713       23537 :       Mnemonic.startswith("vsel") || Mnemonic == "vmaxnm" ||
    5714             :       Mnemonic == "vminnm" || Mnemonic == "vcvta" || Mnemonic == "vcvtn" ||
    5715             :       Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || Mnemonic == "vrinta" ||
    5716             :       Mnemonic == "vrintn" || Mnemonic == "vrintp" || Mnemonic == "vrintm" ||
    5717             :       Mnemonic.startswith("aes") || Mnemonic == "hvc" || Mnemonic == "setpan" ||
    5718             :       Mnemonic.startswith("sha1") || Mnemonic.startswith("sha256") ||
    5719             :       (FullInst.startswith("vmull") && FullInst.endswith(".p64")) ||
    5720       25825 :       Mnemonic == "vmovx" || Mnemonic == "vins" ||
    5721             :       Mnemonic == "vudot" || Mnemonic == "vsdot" ||
    5722             :       Mnemonic == "vcmla" || Mnemonic == "vcadd" ||
    5723       25825 :       Mnemonic == "vfmal" || Mnemonic == "vfmsl" ||
    5724             :       Mnemonic == "sb"    || Mnemonic == "ssbb"  ||
    5725             :       Mnemonic == "pssbb") {
    5726             :     // These mnemonics are never predicable
    5727             :     CanAcceptPredicationCode = false;
    5728             :   } else if (!isThumb()) {
    5729             :     // Some instructions are only predicable in Thumb mode
    5730       21405 :     CanAcceptPredicationCode =
    5731             :         Mnemonic != "cdp2" && Mnemonic != "clrex" && Mnemonic != "mcr2" &&
    5732             :         Mnemonic != "mcrr2" && Mnemonic != "mrc2" && Mnemonic != "mrrc2" &&
    5733             :         Mnemonic != "dmb" && Mnemonic != "dfb" && Mnemonic != "dsb" &&
    5734             :         Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" &&
    5735             :         Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
    5736             :         Mnemonic != "stc2" && Mnemonic != "stc2l" &&
    5737             :         Mnemonic != "tsb" &&
    5738             :         !Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs");
    5739             :   } else if (isThumbOne()) {
    5740             :     if (hasV6MOps())
    5741             :       CanAcceptPredicationCode = Mnemonic != "movs";
    5742             :     else
    5743             :       CanAcceptPredicationCode = Mnemonic != "nop" && Mnemonic != "movs";
    5744             :   } else
    5745             :     CanAcceptPredicationCode = true;
    5746             : }
    5747             : 
    5748             : // Some Thumb instructions have two operand forms that are not
    5749             : // available as three operand, convert to two operand form if possible.
    5750             : //
    5751             : // FIXME: We would really like to be able to tablegen'erate this.
    5752             : void ARMAsmParser::tryConvertingToTwoOperandForm(StringRef Mnemonic,
    5753        4954 :                                                  bool CarrySetting,
    5754       20871 :                                                  OperandVector &Operands) {
    5755             :   if (Operands.size() != 6)
    5756        8023 :     return;
    5757             : 
    5758             :   const auto &Op3 = static_cast<ARMOperand &>(*Operands[3]);
    5759             :         auto &Op4 = static_cast<ARMOperand &>(*Operands[4]);
    5760             :   if (!Op3.isReg() || !Op4.isReg())
    5761             :     return;
    5762             : 
    5763             :   auto Op3Reg = Op3.getReg();
    5764             :   auto Op4Reg = Op4.getReg();
    5765       12848 : 
    5766         990 :   // For most Thumb2 cases we just generate the 3 operand form and reduce
    5767         348 :   // it in processInstruction(), but the 3 operand form of ADD (t2ADDrr)
    5768             :   // won't accept SP or PC so we do the transformation here taking care
    5769         642 :   // with immediate range in the 'add sp, sp #imm' case.
    5770             :   auto &Op5 = static_cast<ARMOperand &>(*Operands[5]);
    5771       11858 :   if (isThumbTwo()) {
    5772       25825 :     if (Mnemonic != "add")
    5773             :       return;
    5774             :     bool TryTransform = Op3Reg == ARM::PC || Op4Reg == ARM::PC ||
    5775             :                         (Op5.isReg() && Op5.getReg() == ARM::PC);
    5776             :     if (!TryTransform) {
    5777             :       TryTransform = (Op3Reg == ARM::SP || Op4Reg == ARM::SP ||
    5778       25522 :                       (Op5.isReg() && Op5.getReg() == ARM::SP)) &&
    5779             :                      !(Op3Reg == ARM::SP && Op4Reg == ARM::SP &&
    5780             :                        Op5.isImm() && !Op5.isImm0_508s4());
    5781       25522 :     }
    5782             :     if (!TryTransform)
    5783             :       return;
    5784             :   } else if (!isThumbOne())
    5785             :     return;
    5786        8215 : 
    5787             :   if (!(Mnemonic == "add" || Mnemonic == "sub" || Mnemonic == "and" ||
    5788             :         Mnemonic == "eor" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
    5789             :         Mnemonic == "asr" || Mnemonic == "adc" || Mnemonic == "sbc" ||
    5790             :         Mnemonic == "ror" || Mnemonic == "orr" || Mnemonic == "bic"))
    5791             :     return;
    5792             : 
    5793             :   // If first 2 operands of a 3 operand instruction are the same
    5794             :   // then transform to 2 operand version of the same instruction
    5795             :   // e.g. 'adds r0, r0, #1' transforms to 'adds r0, #1'
    5796             :   bool Transform = Op3Reg == Op4Reg;
    5797        5269 : 
    5798             :   // For communtative operations, we might be able to transform if we swap
    5799             :   // Op4 and Op5.  The 'ADD Rdm, SP, Rdm' form is already handled specially
    5800         357 :   // as tADDrsp.
    5801          81 :   const ARMOperand *LastOp = &Op5;
    5802             :   bool Swap = false;
    5803         289 :   if (!Transform && Op5.isReg() && Op3Reg == Op5.getReg() &&
    5804         412 :       ((Mnemonic == "add" && Op4Reg != ARM::SP) ||
    5805          61 :        Mnemonic == "and" || Mnemonic == "eor" ||
    5806             :        Mnemonic == "adc" || Mnemonic == "orr")) {
    5807             :     Swap = true;
    5808         357 :     LastOp = &Op4;
    5809             :     Transform = true;
    5810        2737 :   }
    5811             : 
    5812             :   // If both registers are the same then remove one of them from
    5813             :   // the operand list, with certain exceptions.
    5814             :   if (Transform) {
    5815             :     // Don't transform 'adds Rd, Rd, Rm' or 'sub{s} Rd, Rd, Rm' because the
    5816             :     // 2 operand forms don't exist.
    5817             :     if (((Mnemonic == "add" && CarrySetting) || Mnemonic == "sub") &&
    5818             :         LastOp->isReg())
    5819             :       Transform = false;
    5820             : 
    5821             :     // Don't transform 'add/sub{s} Rd, Rd, #imm' if the immediate fits into
    5822         345 :     // 3-bits because the ARMARM says not to.
    5823             :     if ((Mnemonic == "add" || Mnemonic == "sub") && LastOp->isImm0_7())
    5824             :       Transform = false;
    5825             :   }
    5826             : 
    5827             :   if (Transform) {
    5828             :     if (Swap)
    5829         345 :       std::swap(Op4, Op5);
    5830          15 :     Operands.erase(Operands.begin() + 3);
    5831             :   }
    5832             : }
    5833             : 
    5834             : bool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
    5835             :                                           OperandVector &Operands) {
    5836             :   // FIXME: This is all horribly hacky. We really need a better way to deal
    5837             :   // with optional operands like this in the matcher table.
    5838             : 
    5839             :   // The 'mov' mnemonic is special. One variant has a cc_out operand, while
    5840         345 :   // another does not. Specifically, the MOVW instruction does not. So we
    5841             :   // special case it here and remove the defaulted (non-setting) cc_out
    5842             :   // operand if that's the instruction we're trying to match.
    5843         246 :   //
    5844             :   // We do this as post-processing of the explicit operands rather than just
    5845             :   // conditionally adding the cc_out in the first place because we need
    5846             :   // to check the type of the parsed immediate operand.
    5847             :   if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
    5848             :       !static_cast<ARMOperand &>(*Operands[4]).isModImm() &&
    5849         224 :       static_cast<ARMOperand &>(*Operands[4]).isImm0_65535Expr() &&
    5850             :       static_cast<ARMOperand &>(*Operands[1]).getReg() == 0)
    5851             :     return true;
    5852             : 
    5853         138 :   // Register-register 'add' for thumb does not have a cc_out operand
    5854          52 :   // when there are only two register operands.
    5855           8 :   if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
    5856          52 :       static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    5857             :       static_cast<ARMOperand &>(*Operands[4]).isReg() &&
    5858             :       static_cast<ARMOperand &>(*Operands[1]).getReg() == 0)
    5859             :     return true;
    5860       24012 :   // Register-register 'add' for thumb does not have a cc_out operand
    5861             :   // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
    5862             :   // have to check the immediate range here since Thumb2 has a variant
    5863             :   // that can handle a different range and has a cc_out operand.
    5864             :   if (((isThumb() && Mnemonic == "add") ||
    5865             :        (isThumbTwo() && Mnemonic == "sub")) &&
    5866             :       Operands.size() == 6 && static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    5867             :       static_cast<ARMOperand &>(*Operands[4]).isReg() &&
    5868             :       static_cast<ARMOperand &>(*Operands[4]).getReg() == ARM::SP &&
    5869             :       static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 &&
    5870             :       ((Mnemonic == "add" && static_cast<ARMOperand &>(*Operands[5]).isReg()) ||
    5871             :        static_cast<ARMOperand &>(*Operands[5]).isImm0_1020s4()))
    5872             :     return true;
    5873         578 :   // For Thumb2, add/sub immediate does not have a cc_out operand for the
    5874         203 :   // imm0_4095 variant. That's the least-preferred variant when
    5875          11 :   // selecting via the generic "add" mnemonic, so to know that we
    5876             :   // should remove the cc_out operand, we have to explicitly check that
    5877             :   // it's not one of the other variants. Ugh.
    5878             :   if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
    5879             :       Operands.size() == 6 && static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    5880             :       static_cast<ARMOperand &>(*Operands[4]).isReg() &&
    5881         390 :       static_cast<ARMOperand &>(*Operands[5]).isImm()) {
    5882         157 :     // Nest conditions rather than one big 'if' statement for readability.
    5883       24078 :     //
    5884             :     // If both registers are low, we're in an IT block, and the immediate is
    5885             :     // in range, we should use encoding T1 instead, which has a cc_out.
    5886             :     if (inITBlock() &&
    5887             :         isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()) &&
    5888             :         isARMLowRegister(static_cast<ARMOperand &>(*Operands[4]).getReg()) &&
    5889             :         static_cast<ARMOperand &>(*Operands[5]).isImm0_7())
    5890       23611 :       return false;
    5891       23611 :     // Check against T3. If the second register is the PC, this is an
    5892         439 :     // alternate form of ADR, which uses encoding T4, so check for that too.
    5893         228 :     if (static_cast<ARMOperand &>(*Operands[4]).getReg() != ARM::PC &&
    5894          72 :         static_cast<ARMOperand &>(*Operands[5]).isT2SOImm())
    5895       23924 :       return false;
    5896          58 : 
    5897             :     // Otherwise, we use encoding T4, which does not have a cc_out
    5898             :     // operand.
    5899             :     return true;
    5900             :   }
    5901             : 
    5902             :   // The thumb2 multiply instruction doesn't have a CCOut register, so
    5903             :   // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
    5904       23876 :   // use the 16-bit encoding or not.
    5905         375 :   if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
    5906       24051 :       static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 &&
    5907             :       static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    5908             :       static_cast<ARMOperand &>(*Operands[4]).isReg() &&
    5909             :       static_cast<ARMOperand &>(*Operands[5]).isReg() &&
    5910             :       // If the registers aren't low regs, the destination reg isn't the
    5911             :       // same as one of the source regs, or the cc_out operand is zero
    5912         113 :       // outside of an IT block, we have to use the 32-bit encoding, so
    5913             :       // remove the cc_out operand.
    5914         169 :       (!isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()) ||
    5915             :        !isARMLowRegister(static_cast<ARMOperand &>(*Operands[4]).getReg()) ||
    5916             :        !isARMLowRegister(static_cast<ARMOperand &>(*Operands[5]).getReg()) ||
    5917             :        !inITBlock() || (static_cast<ARMOperand &>(*Operands[3]).getReg() !=
    5918             :                             static_cast<ARMOperand &>(*Operands[5]).getReg() &&
    5919          62 :                         static_cast<ARMOperand &>(*Operands[3]).getReg() !=
    5920          62 :                             static_cast<ARMOperand &>(*Operands[4]).getReg())))
    5921          40 :     return true;
    5922             : 
    5923             :   // Also check the 'mul' syntax variant that doesn't specify an explicit
    5924             :   // destination register.
    5925             :   if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
    5926             :       static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 &&
    5927             :       static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    5928             :       static_cast<ARMOperand &>(*Operands[4]).isReg() &&
    5929             :       // If the registers aren't low regs  or the cc_out operand is zero
    5930             :       // outside of an IT block, we have to use the 32-bit encoding, so
    5931       23775 :       // remove the cc_out operand.
    5932          10 :       (!isARMLowRegister(static_cast<ARMOperand &>(*Operands[3]).getReg()) ||
    5933          10 :        !isARMLowRegister(static_cast<ARMOperand &>(*Operands[4]).getReg()) ||
    5934          10 :        !inITBlock()))
    5935       23763 :     return true;
    5936             : 
    5937             :   // Register-register 'add/sub' for thumb does not have a cc_out operand
    5938             :   // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
    5939             :   // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
    5940             :   // right, this will result in better diagnostics (which operand is off)
    5941             :   // anyway.
    5942           8 :   if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
    5943           8 :       (Operands.size() == 5 || Operands.size() == 6) &&
    5944           3 :       static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    5945             :       static_cast<ARMOperand &>(*Operands[3]).getReg() == ARM::SP &&
    5946             :       static_cast<ARMOperand &>(*Operands[1]).getReg() == 0 &&
    5947             :       (static_cast<ARMOperand &>(*Operands[4]).isImm() ||
    5948             :        (Operands.size() == 6 &&
    5949             :         static_cast<ARMOperand &>(*Operands[5]).isImm())))
    5950             :     return true;
    5951       23757 : 
    5952           2 :   return false;
    5953           2 : }
    5954       23754 : 
    5955             : bool ARMAsmParser::shouldOmitPredicateOperand(StringRef Mnemonic,
    5956             :                                               OperandVector &Operands) {
    5957             :   // VRINT{Z, X} have a predicate operand in VFP, but not in NEON
    5958             :   unsigned RegIdx = 3;
    5959           2 :   if ((Mnemonic == "vrintz" || Mnemonic == "vrintx") &&
    5960           2 :       (static_cast<ARMOperand &>(*Operands[2]).getToken() == ".f32" ||
    5961             :        static_cast<ARMOperand &>(*Operands[2]).getToken() == ".f16")) {
    5962             :     if (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
    5963             :         (static_cast<ARMOperand &>(*Operands[3]).getToken() == ".f32" ||
    5964             :          static_cast<ARMOperand &>(*Operands[3]).getToken() == ".f16"))
    5965             :       RegIdx = 4;
    5966             : 
    5967             :     if (static_cast<ARMOperand &>(*Operands[RegIdx]).isReg() &&
    5968         281 :         (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(
    5969         281 :              static_cast<ARMOperand &>(*Operands[RegIdx]).getReg()) ||
    5970         166 :          ARMMCRegisterClasses[ARM::QPRRegClassID].contains(
    5971          45 :              static_cast<ARMOperand &>(*Operands[RegIdx]).getReg())))
    5972       23797 :       return true;
    5973           5 :   }
    5974           3 :   return false;
    5975             : }
    5976          41 : 
    5977             : static bool isDataTypeToken(StringRef Tok) {
    5978             :   return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
    5979             :     Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
    5980             :     Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
    5981           0 :     Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
    5982             :     Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
    5983             :     Tok == ".f" || Tok == ".d";
    5984             : }
    5985             : 
    5986           0 : // FIXME: This bit should probably be handled via an explicit match class
    5987             : // in the .td files that matches the suffix instead of having it be
    5988           0 : // a literal string token the way it is now.
    5989           0 : static bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
    5990             :   return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
    5991             : }
    5992             : 
    5993           0 : static void applyMnemonicAliases(StringRef &Mnemonic, uint64_t Features,
    5994           0 :                                  unsigned VariantID);
    5995           0 : 
    5996           0 : // The GNU assembler has aliases of ldrd and strd with the second register
    5997             : // omitted. We don't have a way to do that in tablegen, so fix it up here.
    5998           0 : //
    5999             : // We have to be careful to not emit an invalid Rt2 here, because the rest of
    6000             : // the assmebly parser could then generate confusing diagnostics refering to
    6001             : // it. If we do find anything that prevents us from doing the transformation we
    6002             : // bail out, and let the assembly parser report an error on the instruction as
    6003       10515 : // it is written.
    6004             : void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
    6005             :                                      OperandVector &Operands) {
    6006             :   if (Mnemonic != "ldrd" && Mnemonic != "strd")
    6007             :     return;
    6008             :   if (Operands.size() < 4)
    6009       10515 :     return;
    6010             : 
    6011             :   ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[2]);
    6012             :   ARMOperand &Op3 = static_cast<ARMOperand &>(*Operands[3]);
    6013             : 
    6014             :   if (!Op2.isReg())
    6015           0 :     return;
    6016           0 :   if (!Op3.isMem())
    6017             :     return;
    6018             : 
    6019             :   const MCRegisterClass &GPR = MRI->getRegClass(ARM::GPRRegClassID);
    6020             :   if (!GPR.contains(Op2.getReg()))
    6021             :     return;
    6022             : 
    6023             :   unsigned RtEncoding = MRI->getEncodingValue(Op2.getReg());
    6024             :   if (!isThumb() && (RtEncoding & 1)) {
    6025             :     // In ARM mode, the registers must be from an aligned pair, this
    6026             :     // restriction does not apply in Thumb mode.
    6027             :     return;
    6028             :   }
    6029             :   if (Op2.getReg() == ARM::PC)
    6030       25518 :     return;
    6031             :   unsigned PairedReg = GPR.getRegister(RtEncoding + 1);
    6032             :   if (!PairedReg || PairedReg == ARM::PC ||
    6033             :       (PairedReg == ARM::SP && !hasV8Ops()))
    6034         277 :     return;
    6035             : 
    6036             :   Operands.insert(
    6037             :       Operands.begin() + 3,
    6038             :       ARMOperand::CreateReg(PairedReg, Op2.getStartLoc(), Op2.getEndLoc()));
    6039             : }
    6040         269 : 
    6041             : /// Parse an arm instruction mnemonic followed by its operands.
    6042         269 : bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
    6043             :                                     SMLoc NameLoc, OperandVector &Operands) {
    6044             :   MCAsmParser &Parser = getParser();
    6045          40 : 
    6046          40 :   // Apply mnemonic aliases before doing anything else, as the destination
    6047             :   // mnemonic may include suffices and we want to handle them normally.
    6048             :   // The generic tblgen'erated code does this later, at the start of
    6049          72 :   // MatchInstructionImpl(), but that's too late for aliases that include
    6050          36 :   // any sort of suffix.
    6051             :   uint64_t AvailableFeatures = getAvailableFeatures();
    6052             :   unsigned AssemblerDialect = getParser().getAssemblerDialect();
    6053             :   applyMnemonicAliases(Name, AvailableFeatures, AssemblerDialect);
    6054             : 
    6055          34 :   // First check for the ARM-specific .req directive.
    6056             :   if (Parser.getTok().is(AsmToken::Identifier) &&
    6057          34 :       Parser.getTok().getIdentifier() == ".req") {
    6058          34 :     parseDirectiveReq(Name, NameLoc);
    6059          12 :     // We always return 'error' for this, as we're done with this
    6060           8 :     // statement and don't need to match the 'instruction."
    6061             :     return true;
    6062          26 :   }
    6063             : 
    6064          26 :   // Create the leading tokens for the mnemonic, split by '.' characters.
    6065             :   size_t Start = 0, Next = Name.find('.');
    6066             :   StringRef Mnemonic = Name.slice(Start, Next);
    6067             : 
    6068       25840 :   // Split out the predication code and carry setting flag from the mnemonic.
    6069             :   unsigned PredicationCode;
    6070       25840 :   unsigned ProcessorIMod;
    6071             :   bool CarrySetting;
    6072             :   StringRef ITMask;
    6073             :   Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
    6074             :                            ProcessorIMod, ITMask);
    6075             : 
    6076             :   // In Thumb1, only the branch (B) instruction can be predicated.
    6077       25840 :   if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
    6078       25840 :     return Error(NameLoc, "conditional execution not supported in Thumb1");
    6079       25840 :   }
    6080             : 
    6081             :   Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
    6082       25840 : 
    6083       21428 :   // Handle the IT instruction ITMask. Convert it to a bitmask. This
    6084           7 :   // is the mask as it will be for the IT encoding if the conditional
    6085             :   // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
    6086             :   // where the conditional bit0 is zero, the instruction post-processing
    6087           7 :   // will adjust the mask accordingly.
    6088             :   if (Mnemonic == "it") {
    6089             :     SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
    6090             :     if (ITMask.size() > 3) {
    6091             :       return Error(Loc, "too many conditions on IT instruction");
    6092       25833 :     }
    6093             :     unsigned Mask = 8;
    6094             :     for (unsigned i = ITMask.size(); i != 0; --i) {
    6095             :       char pos = ITMask[i - 1];
    6096             :       if (pos != 't' && pos != 'e') {
    6097             :         return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
    6098       25833 :       }
    6099             :       Mask >>= 1;
    6100       25833 :       if (ITMask[i - 1] == 't')
    6101             :         Mask |= 8;
    6102             :     }
    6103       25833 :     Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
    6104           4 :   }
    6105             : 
    6106             :   // FIXME: This is all a pretty gross hack. We should automatically handle
    6107       51658 :   // optional operands like this via tblgen.
    6108             : 
    6109             :   // Next, add the CCOut and ConditionCode operands, if needed.
    6110             :   //
    6111             :   // For mnemonics which can ever incorporate a carry setting bit or predication
    6112             :   // code, our matching model involves us always generating CCOut and
    6113             :   // ConditionCode operands to match the mnemonic "as written" and then we let
    6114             :   // the matcher deal with finding the right instruction or generating an
    6115        2791 :   // appropriate error.
    6116        2791 :   bool CanAcceptCarrySet, CanAcceptPredicationCode;
    6117           2 :   getMnemonicAcceptInfo(Mnemonic, Name, CanAcceptCarrySet, CanAcceptPredicationCode);
    6118             : 
    6119             :   // If we had a carry-set on an instruction that can't do that, issue an
    6120        3094 :   // error.
    6121         307 :   if (!CanAcceptCarrySet && CarrySetting) {
    6122         307 :     return Error(NameLoc, "instruction '" + Mnemonic +
    6123           2 :                  "' can not set flags, but 's' suffix specified");
    6124             :   }
    6125         305 :   // If we had a predication code on an instruction that can't do that, issue an
    6126         305 :   // error.
    6127         152 :   if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
    6128             :     return Error(NameLoc, "instruction '" + Mnemonic +
    6129        5574 :                  "' is not predicable, but condition code specified");
    6130             :   }
    6131             : 
    6132             :   // Add the carry setting operand, if necessary.
    6133             :   if (CanAcceptCarrySet) {
    6134             :     SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
    6135             :     Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
    6136             :                                                Loc));
    6137             :   }
    6138             : 
    6139             :   // Add the predication code operand, if necessary.
    6140             :   if (CanAcceptPredicationCode) {
    6141             :     SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
    6142             :                                       CarrySetting);
    6143       25825 :     Operands.push_back(ARMOperand::CreateCondCode(
    6144             :                          ARMCC::CondCodes(PredicationCode), Loc));
    6145             :   }
    6146             : 
    6147       25825 :   // Add the processor imod operand, if necessary.
    6148           4 :   if (ProcessorIMod) {
    6149           4 :     Operands.push_back(ARMOperand::CreateImm(
    6150             :           MCConstantExpr::create(ProcessorIMod, getContext()),
    6151             :                                  NameLoc, NameLoc));
    6152             :   } else if (Mnemonic == "cps" && isMClass()) {
    6153       25821 :     return Error(NameLoc, "instruction 'cps' requires effect for M-class");
    6154          84 :   }
    6155          84 : 
    6156             :   // Add the remaining tokens in the mnemonic.
    6157             :   while (Next != StringRef::npos) {
    6158             :     Start = Next;
    6159       25737 :     Next = Name.find('.', Start + 1);
    6160        4705 :     StringRef ExtraToken = Name.slice(Start, Next);
    6161       14115 : 
    6162             :     // Some NEON instructions have an optional datatype suffix that is
    6163             :     // completely ignored. Check for that.
    6164             :     if (isDataTypeToken(ExtraToken) &&
    6165             :         doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
    6166       25737 :       continue;
    6167       20381 : 
    6168       20381 :     // For for ARM mode generate an error if the .n qualifier is used.
    6169       40762 :     if (ExtraToken == ".n" && !isThumb()) {
    6170             :       SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
    6171             :       return Error(Loc, "instruction with .n (narrow) qualifier not allowed in "
    6172             :                    "arm mode");
    6173             :     }
    6174       25737 : 
    6175          88 :     // The .n qualifier is always discarded as that is what the tables
    6176          44 :     // and matcher expect.  In ARM mode the .w qualifier has no effect,
    6177             :     // so discard it to avoid errors that can be caused by the matcher.
    6178          14 :     if (ExtraToken != ".n" && (isThumb() || ExtraToken != ".w")) {
    6179           1 :       SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
    6180             :       Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
    6181             :     }
    6182             :   }
    6183       36248 : 
    6184             :   // Read the remaining operands.
    6185       21030 :   if (getLexer().isNot(AsmToken::EndOfStatement)) {
    6186       10515 :     // Read the first operand.
    6187             :     if (parseOperand(Operands, Mnemonic)) {
    6188             :       return true;
    6189             :     }
    6190       10515 : 
    6191        7965 :     while (parseOptionalToken(AsmToken::Comma)) {
    6192             :       // Parse and remember the operand.
    6193             :       if (parseOperand(Operands, Mnemonic)) {
    6194             :         return true;
    6195          30 :       }
    6196           3 :     }
    6197           3 :   }
    6198             : 
    6199             :   if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
    6200             :     return true;
    6201             : 
    6202             :   tryConvertingToTwoOperandForm(Mnemonic, CarrySetting, Operands);
    6203             : 
    6204       10485 :   // Some instructions, mostly Thumb, have forms for the same mnemonic that
    6205       10475 :   // do and don't have a cc_out optional-def operand. With some spot-checks
    6206       20950 :   // of the operand list, we can figure out which variant we're trying to
    6207             :   // parse and adjust accordingly before actually matching. We shouldn't ever
    6208             :   // try to remove a cc_out operand that was explicitly set on the
    6209             :   // mnemonic, of course (CarrySetting == true). Reason number #317 the
    6210             :   // table driven matcher doesn't fit well with the ARM instruction set.
    6211       25733 :   if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands))
    6212             :     Operands.erase(Operands.begin() + 1);
    6213       25217 : 
    6214             :   // Some instructions have the same mnemonic, but don't always
    6215             :   // have a predicate. Distinguish them here and delete the
    6216             :   // predicate if needed.
    6217       57767 :   if (PredicationCode == ARMCC::AL &&
    6218             :       shouldOmitPredicateOperand(Mnemonic, Operands))
    6219       32753 :     Operands.erase(Operands.begin() + 1);
    6220             : 
    6221             :   // ARM mode 'blx' need special handling, as the register operand version
    6222             :   // is predicable, but the label operand version is not. So, we can't rely
    6223             :   // on the Mnemonic based checking to correctly figure out when to put
    6224             :   // a k_CondCode operand in the list. If we're trying to match the label
    6225       25530 :   // version, remove the k_CondCode operand here.
    6226             :   if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
    6227             :       static_cast<ARMOperand &>(*Operands[2]).isImm())
    6228       25522 :     Operands.erase(Operands.begin() + 1);
    6229             : 
    6230             :   // Adjust operands of ldrexd/strexd to MCK_GPRPair.
    6231             :   // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
    6232             :   // a single GPRPair reg operand is used in the .td file to replace the two
    6233             :   // GPRs. However, when parsing from asm, the two GRPs cannot be automatically
    6234             :   // expressed as a GPRPair, so we have to manually merge them.
    6235             :   // FIXME: We would really like to be able to tablegen'erate this.
    6236             :   if (!isThumb() && Operands.size() > 4 &&
    6237       25522 :       (Mnemonic == "ldrexd" || Mnemonic == "strexd" || Mnemonic == "ldaexd" ||
    6238         210 :        Mnemonic == "stlexd")) {
    6239             :     bool isLoad = (Mnemonic == "ldrexd" || Mnemonic == "ldaexd");
    6240             :     unsigned Idx = isLoad ? 2 : 3;
    6241             :     ARMOperand &Op1 = static_cast<ARMOperand &>(*Operands[Idx]);
    6242             :     ARMOperand &Op2 = static_cast<ARMOperand &>(*Operands[Idx + 1]);
    6243       25522 : 
    6244       21699 :     const MCRegisterClass& MRC = MRI->getRegClass(ARM::GPRRegClassID);
    6245          37 :     // Adjust only if Op1 and Op2 are GPRs.
    6246             :     if (Op1.isReg() && Op2.isReg() && MRC.contains(Op1.getReg()) &&
    6247             :         MRC.contains(Op2.getReg())) {
    6248             :       unsigned Reg1 = Op1.getReg();
    6249             :       unsigned Reg2 = Op2.getReg();
    6250             :       unsigned Rt = MRI->getEncodingValue(Reg1);
    6251             :       unsigned Rt2 = MRI->getEncodingValue(Reg2);
    6252       25550 : 
    6253             :       // Rt2 must be Rt + 1 and Rt must be even.
    6254          22 :       if (Rt + 1 != Rt2 || (Rt & 1)) {
    6255             :         return Error(Op2.getStartLoc(),
    6256             :                      isLoad ? "destination operands must be sequential"
    6257             :                             : "source operands must be sequential");
    6258             :       }
    6259             :       unsigned NewReg = MRI->getMatchingSuperReg(Reg1, ARM::gsub_0,
    6260             :           &(MRI->getRegClass(ARM::GPRPairRegClassID)));
    6261             :       Operands[Idx] =
    6262       25522 :           ARMOperand::CreateReg(NewReg, Op1.getStartLoc(), Op2.getEndLoc());
    6263             :       Operands.erase(Operands.begin() + Idx + 1);
    6264             :     }
    6265             :   }
    6266             : 
    6267          26 :   // GNU Assembler extension (compatibility).
    6268          26 :   fixupGNULDRDAlias(Mnemonic, Operands);
    6269             : 
    6270          26 :   // FIXME: As said above, this is all a pretty gross hack.  This instruction
    6271             :   // does not fit with other "subs" and tblgen.
    6272          52 :   // Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
    6273             :   // so the Mnemonic is the original name "subs" and delete the predicate
    6274             :   // operand so it will match the table entry.
    6275             :   if (isThumbTwo() && Mnemonic == "sub" && Operands.size() == 6 &&
    6276          52 :       static_cast<ARMOperand &>(*Operands[3]).isReg() &&
    6277          26 :       static_cast<ARMOperand &>(*Operands[3]).getReg() == ARM::PC &&
    6278             :       static_cast<ARMOperand &>(*Operands[4]).isReg() &&
    6279             :       static_cast<ARMOperand &>(*Operands[4]).getReg() == ARM::LR &&
    6280          26 :       static_cast<ARMOperand &>(*Operands[5]).isImm()) {
    6281           8 :     Operands.front() = ARMOperand::CreateToken(Name, NameLoc);
    6282             :     Operands.erase(Operands.begin() + 1);
    6283             :   }
    6284             :   return false;
    6285          22 : }
    6286             : 
    6287             : // Validate context-sensitive operand constraints.
    6288          22 : 
    6289          22 : // return 'true' if register list contains non-low GPR registers,
    6290             : // 'false' otherwise. If Reg is in the register list or is HiReg, set
    6291             : // 'containsReg' to true.
    6292             : static bool checkLowRegisterList(const MCInst &Inst, unsigned OpNo,
    6293             :                                  unsigned Reg, unsigned HiReg,
    6294       25518 :                                  bool &containsReg) {
    6295             :   containsReg = false;
    6296             :   for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
    6297             :     unsigned OpReg = Inst.getOperand(i).getReg();
    6298             :     if (OpReg == Reg)
    6299             :       containsReg = true;
    6300             :     // Anything other than a low register isn't legal here.
    6301       25719 :     if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
    6302          58 :       return true;
    6303           4 :   }
    6304           4 :   return false;
    6305       25522 : }
    6306             : 
    6307           8 : // Check if the specified regisgter is in the register list of the inst,
    6308           4 : // starting at the indicated operand number.
    6309             : static bool listContainsReg(const MCInst &Inst, unsigned OpNo, unsigned Reg) {
    6310             :   for (unsigned i = OpNo, e = Inst.getNumOperands(); i < e; ++i) {
    6311             :     unsigned OpReg = Inst.getOperand(i).getReg();
    6312             :     if (OpReg == Reg)
    6313             :       return true;
    6314             :   }
    6315             :   return false;
    6316             : }
    6317             : 
    6318             : // Return true if instruction has the interesting property of being
    6319             : // allowed in IT blocks, but not being predicable.
    6320             : static bool instIsBreakpoint(const MCInst &Inst) {
    6321             :     return Inst.getOpcode() == ARM::tBKPT ||
    6322         911 :            Inst.getOpcode() == ARM::BKPT ||
    6323         333 :            Inst.getOpcode() == ARM::tHLT ||
    6324         424 :            Inst.getOpcode() == ARM::HLT;
    6325             : }
    6326             : 
    6327         113 : bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst,
    6328             :                                        const OperandVector &Operands,
    6329             :                                        unsigned ListNo, bool IsARPop) {
    6330             :   const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]);
    6331             :   bool HasWritebackToken = Op.isToken() && Op.getToken() == "!";
    6332             : 
    6333             :   bool ListContainsSP = listContainsReg(Inst, ListNo, ARM::SP);
    6334             :   bool ListContainsLR = listContainsReg(Inst, ListNo, ARM::LR);
    6335             :   bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC);
    6336        3030 : 
    6337        2328 :   if (!IsARPop && ListContainsSP)
    6338        2328 :     return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
    6339             :                  "SP may not be in the register list");
    6340             :   else if (ListContainsPC && ListContainsLR)
    6341             :     return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
    6342             :                  "PC and LR may not be in the register list simultaneously");
    6343             :   return false;
    6344             : }
    6345             : 
    6346             : bool ARMAsmParser::validatetSTMRegList(const MCInst &Inst,
    6347        3160 :                                        const OperandVector &Operands,
    6348        3160 :                                        unsigned ListNo) {
    6349        6321 :   const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]);
    6350             :   bool HasWritebackToken = Op.isToken() && Op.getToken() == "!";
    6351             : 
    6352             :   bool ListContainsSP = listContainsReg(Inst, ListNo, ARM::SP);
    6353         146 :   bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC);
    6354             : 
    6355             :   if (ListContainsSP && ListContainsPC)
    6356         146 :     return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
    6357         146 :                  "SP and PC may not be in the register list");
    6358             :   else if (ListContainsSP)
    6359             :     return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
    6360             :                  "SP may not be in the register list");
    6361             :   else if (ListContainsPC)
    6362             :     return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
    6363         146 :                  "PC may not be in the register list");
    6364          69 :   return false;
    6365             : }
    6366         123 : 
    6367          27 : bool ARMAsmParser::validateLDRDSTRD(MCInst &Inst,
    6368             :                                     const OperandVector &Operands,
    6369             :                                     bool Load, bool ARMMode, bool Writeback) {
    6370             :   unsigned RtIndex = Load || !Writeback ? 0 : 1;
    6371             :   unsigned Rt = MRI->getEncodingValue(Inst.getOperand(RtIndex).getReg());
    6372         128 :   unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(RtIndex + 1).getReg());
    6373             : 
    6374             :   if (ARMMode) {
    6375         128 :     // Rt can't be R14.
    6376         128 :     if (Rt == 14)
    6377             :       return Error(Operands[3]->getStartLoc(),
    6378             :                   "Rt can't be R14");
    6379             : 
    6380             :     // Rt must be even-numbered.
    6381         128 :     if ((Rt & 1) == 1)
    6382          27 :       return Error(Operands[3]->getStartLoc(),
    6383             :                    "Rt must be even-numbered");
    6384         119 : 
    6385          51 :     // Rt2 must be Rt + 1.
    6386             :     if (Rt2 != Rt + 1) {
    6387         102 :       if (Load)
    6388          27 :         return Error(Operands[3]->getStartLoc(),
    6389             :                      "destination operands must be sequential");
    6390             :       else
    6391             :         return Error(Operands[3]->getStartLoc(),
    6392             :                      "source operands must be sequential");
    6393         199 :     }
    6394             : 
    6395             :     // FIXME: Diagnose m == 15
    6396         199 :     // FIXME: Diagnose ldrd with m == t || m == t2.
    6397         398 :   }
    6398         398 : 
    6399             :   if (!ARMMode && Load) {
    6400         199 :     if (Rt2 == Rt)
    6401             :       return Error(Operands[3]->getStartLoc(),
    6402          88 :                    "destination operands can't be identical");
    6403          22 :   }
    6404             : 
    6405             :   if (Writeback) {
    6406             :     unsigned Rn = MRI->getEncodingValue(Inst.getOperand(3).getReg());
    6407          77 : 
    6408          22 :     if (Rn == Rt || Rn == Rt2) {
    6409             :       if (Load)
    6410             :         return Error(Operands[3]->getStartLoc(),
    6411             :                      "base register needs to be different from destination "
    6412          66 :                      "registers");
    6413          19 :       else
    6414          26 :         return Error(Operands[3]->getStartLoc(),
    6415             :                      "source register and base register can't be identical");
    6416             :     }
    6417          12 : 
    6418             :     // FIXME: Diagnose ldrd/strd with writeback and n == 15.
    6419             :     // (Except the immediate form of ldrd?)
    6420             :   }
    6421             : 
    6422             :   return false;
    6423             : }
    6424             : 
    6425         158 : 
    6426          29 : // FIXME: We would really like to be able to tablegen'erate this.
    6427           8 : bool ARMAsmParser::validateInstruction(MCInst &Inst,
    6428             :                                        const OperandVector &Operands) {
    6429             :   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
    6430             :   SMLoc Loc = Operands[0]->getStartLoc();
    6431         154 : 
    6432         128 :   // Check the IT block state first.
    6433             :   // NOTE: BKPT and HLT instructions have the interesting property of being
    6434         128 :   // allowed in IT blocks, but not being predicable. They just always execute.
    6435          16 :   if (inITBlock() && !instIsBreakpoint(Inst)) {
    6436          16 :     // The instruction must be predicable.
    6437             :     if (!MCID.isPredicable())
    6438             :       return Error(Loc, "instructions in IT block must be predicable");
    6439             :     ARMCC::CondCodes Cond = ARMCC::CondCodes(
    6440          16 :         Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm());
    6441             :     if (Cond != currentITCond()) {
    6442             :       // Find the condition code Operand to get its SMLoc information.
    6443             :       SMLoc CondLoc;
    6444             :       for (unsigned I = 1; I < Operands.size(); ++I)
    6445             :         if (static_cast<ARMOperand &>(*Operands[I]).isCondCode())
    6446             :           CondLoc = Operands[I]->getStartLoc();
    6447             :       return Error(CondLoc, "incorrect condition in IT block; got '" +
    6448             :                                 StringRef(ARMCondCodeToString(Cond)) +
    6449             :                                 "', but expected '" +
    6450             :                                 ARMCondCodeToString(currentITCond()) + "'");
    6451             :     }
    6452             :   // Check for non-'al' condition codes outside of the IT block.
    6453       21193 :   } else if (isThumbTwo() && MCID.isPredicable() &&
    6454             :              Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
    6455       21193 :              ARMCC::AL && Inst.getOpcode() != ARM::tBcc &&
    6456       21193 :              Inst.getOpcode() != ARM::t2Bcc) {
    6457             :     return Error(Loc, "predicated instructions must be in IT block");
    6458             :   } else if (!isThumb() && !useImplicitITARM() && MCID.isPredicable() &&
    6459             :              Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
    6460             :                  ARMCC::AL) {
    6461       21193 :     return Warning(Loc, "predicated instructions should be in IT block");
    6462             :   }
    6463        6318 : 
    6464          10 :   // PC-setting instructions in an IT block, but not the last instruction of
    6465             :   // the block, are UNPREDICTABLE.
    6466        6298 :   if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) {
    6467        3149 :     return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block");
    6468             :   }
    6469             : 
    6470         136 :   const unsigned Opcode = Inst.getOpcode();
    6471         112 :   switch (Opcode) {
    6472          24 :   case ARM::t2IT: {
    6473          48 :     // Encoding is unpredictable if it ever results in a notional 'NV'
    6474          24 :     // predicate. Since we don't parse 'NV' directly this means an 'AL'
    6475          48 :     // predicate with an "else" mask bit.
    6476          48 :     unsigned Cond = Inst.getOperand(0).getImm();
    6477             :     unsigned Mask = Inst.getOperand(1).getImm();
    6478             : 
    6479       37412 :     // Mask hasn't been modified to the IT instruction encoding yet so
    6480       13126 :     // conditions only allowing a 't' are a block of 1s starting at bit 3
    6481       18198 :     // followed by all 0s. Easiest way is to just list the 4 possibilities.
    6482             :     if (Cond == ARMCC::AL && Mask != 8 && Mask != 12 && Mask != 14 &&
    6483           5 :         Mask != 15)
    6484       18049 :       return Error(Loc, "unpredictable IT predicate sequence");
    6485           4 :     break;
    6486             :   }
    6487           2 :   case ARM::LDRD:
    6488             :     if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/true,
    6489             :                          /*Writeback*/false))
    6490             :       return true;
    6491             :     break;
    6492        3014 :   case ARM::LDRD_PRE:
    6493          28 :   case ARM::LDRD_POST:
    6494             :     if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/true,
    6495             :                          /*Writeback*/true))
    6496       21124 :       return true;
    6497       21124 :     break;
    6498             :   case ARM::t2LDRDi8:
    6499             :     if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/false,
    6500             :                          /*Writeback*/false))
    6501             :       return true;
    6502        2720 :     break;
    6503        2720 :   case ARM::t2LDRD_PRE:
    6504             :   case ARM::t2LDRD_POST:
    6505             :     if (validateLDRDSTRD(Inst, Operands, /*Load*/true, /*ARMMode*/false,
    6506             :                          /*Writeback*/true))
    6507             :       return true;
    6508        2720 :     break;
    6509             :   case ARM::t2BXJ: {
    6510           5 :     const unsigned RmReg = Inst.getOperand(0).getReg();
    6511             :     // Rm = SP is no longer unpredictable in v8-A
    6512             :     if (RmReg == ARM::SP && !hasV8Ops())
    6513          21 :       return Error(Operands[2]->getStartLoc(),
    6514          21 :                    "r13 (SP) is an unpredictable operand to BXJ");
    6515             :     return false;
    6516          13 :   }
    6517             :   case ARM::STRD:
    6518          36 :     if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/true,
    6519             :                          /*Writeback*/false))
    6520          36 :       return true;
    6521             :     break;
    6522          26 :   case ARM::STRD_PRE:
    6523             :   case ARM::STRD_POST:
    6524          13 :     if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/true,
    6525          13 :                          /*Writeback*/true))
    6526             :       return true;
    6527           2 :     break;
    6528             :   case ARM::t2STRD_PRE:
    6529          16 :   case ARM::t2STRD_POST:
    6530             :     if (validateLDRDSTRD(Inst, Operands, /*Load*/false, /*ARMMode*/false,
    6531          16 :                          /*Writeback*/true))
    6532             :       return true;
    6533           2 :     break;
    6534             :   case ARM::STR_PRE_IMM:
    6535             :   case ARM::STR_PRE_REG:
    6536          13 :   case ARM::t2STR_PRE:
    6537             :   case ARM::STR_POST_IMM:
    6538          17 :   case ARM::STR_POST_REG:
    6539           6 :   case ARM::t2STR_POST:
    6540             :   case ARM::STRH_PRE:
    6541             :   case ARM::t2STRH_PRE:
    6542             :   case ARM::STRH_POST:
    6543          11 :   case ARM::t2STRH_POST:
    6544          11 :   case ARM::STRB_PRE_IMM:
    6545             :   case ARM::STRB_PRE_REG:
    6546           4 :   case ARM::t2STRB_PRE:
    6547             :   case ARM::STRB_POST_IMM:
    6548          20 :   case ARM::STRB_POST_REG:
    6549             :   case ARM::t2STRB_POST: {
    6550          20 :     // Rt must be different from Rn.
    6551             :     const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
    6552          10 :     const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
    6553             : 
    6554          82 :     if (Rt == Rn)
    6555             :       return Error(Operands[3]->getStartLoc(),
    6556          82 :                    "source register and base register can't be identical");
    6557             :     return false;
    6558           4 :   }
    6559             :   case ARM::LDR_PRE_IMM:
    6560         106 :   case ARM::LDR_PRE_REG:
    6561             :   case ARM::t2LDR_PRE:
    6562             :   case ARM::LDR_POST_IMM:
    6563             :   case ARM::LDR_POST_REG:
    6564             :   case ARM::t2LDR_POST:
    6565             :   case ARM::LDRH_PRE:
    6566             :   case ARM::t2LDRH_PRE:
    6567             :   case ARM::LDRH_POST:
    6568             :   case ARM::t2LDRH_POST:
    6569             :   case ARM::LDRSH_PRE:
    6570             :   case ARM::t2LDRSH_PRE:
    6571             :   case ARM::LDRSH_POST:
    6572             :   case ARM::t2LDRSH_POST:
    6573             :   case ARM::LDRB_PRE_IMM:
    6574             :   case ARM::LDRB_PRE_REG:
    6575             :   case ARM::t2LDRB_PRE:
    6576             :   case ARM::LDRB_POST_IMM:
    6577         212 :   case ARM::LDRB_POST_REG:
    6578         106 :   case ARM::t2LDRB_POST:
    6579             :   case ARM::LDRSB_PRE:
    6580         106 :   case ARM::t2LDRSB_PRE:
    6581          72 :   case ARM::LDRSB_POST:
    6582             :   case ARM::t2LDRSB_POST: {
    6583             :     // Rt must be different from Rn.
    6584             :     const unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
    6585         141 :     const unsigned Rn = MRI->getEncodingValue(Inst.getOperand(2).getReg());
    6586             : 
    6587             :     if (Rt == Rn)
    6588             :       return Error(Operands[3]->getStartLoc(),
    6589             :                    "destination register and base register can't be identical");
    6590             :     return false;
    6591             :   }
    6592             :   case ARM::SBFX:
    6593             :   case ARM::t2SBFX:
    6594             :   case ARM::UBFX:
    6595             :   case ARM::t2UBFX: {
    6596             :     // Width must be in range [1, 32-lsb].
    6597             :     unsigned LSB = Inst.getOperand(2).getImm();
    6598             :     unsigned Widthm1 = Inst.getOperand(3).getImm();
    6599             :     if (Widthm1 >= 32 - LSB)
    6600             :       return Error(Operands[5]->getStartLoc(),
    6601             :                    "bitfield width must be in range [1,32-lsb]");
    6602             :     return false;
    6603             :   }
    6604             :   // Notionally handles ARM::tLDMIA_UPD too.
    6605             :   case ARM::tLDMIA: {
    6606             :     // If we're parsing Thumb2, the .w variant is available and handles
    6607             :     // most cases that are normally illegal for a Thumb1 LDM instruction.
    6608             :     // We'll make the transformation in processInstruction() if necessary.
    6609             :     //
    6610         282 :     // Thumb LDM instructions are writeback iff the base register is not
    6611         141 :     // in the register list.
    6612             :     unsigned Rn = Inst.getOperand(0).getReg();
    6613         141 :     bool HasWritebackToken =
    6614          80 :         (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
    6615             :          static_cast<ARMOperand &>(*Operands[3]).getToken() == "!");
    6616             :     bool ListContainsBase;
    6617             :     if (checkLowRegisterList(Inst, 3, Rn, 0, ListContainsBase) && !isThumbTwo())
    6618             :       return Error(Operands[3 + HasWritebackToken]->getStartLoc(),
    6619             :                    "registers must be in range r0-r7");
    6620             :     // If we should have writeback, then there should be a '!' token.
    6621             :     if (!ListContainsBase && !HasWritebackToken && !isThumbTwo())
    6622             :       return Error(Operands[2]->getStartLoc(),
    6623          80 :                    "writeback operator '!' expected");
    6624          80 :     // If we should not have writeback, there must not be a '!'. This is
    6625          80 :     // true even for the 32-bit wide encodings.
    6626          16 :     if (ListContainsBase && HasWritebackToken)
    6627             :       return Error(Operands[3]->getStartLoc(),
    6628             :                    "writeback operator '!' not allowed when base register "
    6629             :                    "in register list");
    6630             : 
    6631             :     if (validatetLDMRegList(Inst, Operands, 3))
    6632             :       return true;
    6633             :     break;
    6634             :   }
    6635             :   case ARM::LDMIA_UPD:
    6636             :   case ARM::LDMDB_UPD:
    6637             :   case ARM::LDMIB_UPD:
    6638          75 :   case ARM::LDMDA_UPD:
    6639             :     // ARM variants loading and updating the same register are only officially
    6640          75 :     // UNPREDICTABLE on v7 upwards. Goodness knows what they did before.
    6641          43 :     if (!hasV7Ops())
    6642             :       break;
    6643          52 :     if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
    6644          42 :       return Error(Operands.back()->getStartLoc(),
    6645             :                    "writeback register not allowed in register list");
    6646             :     break;
    6647          61 :   case ARM::t2LDMIA:
    6648           4 :   case ARM::t2LDMDB:
    6649             :     if (validatetLDMRegList(Inst, Operands, 3))
    6650             :       return true;
    6651             :     break;
    6652          59 :   case ARM::t2STMIA:
    6653          12 :   case ARM::t2STMDB:
    6654             :     if (validatetSTMRegList(Inst, Operands, 3))
    6655             :       return true;
    6656             :     break;
    6657          53 :   case ARM::t2LDMIA_UPD:
    6658          16 :   case ARM::t2LDMDB_UPD:
    6659             :   case ARM::t2STMIA_UPD:
    6660             :   case ARM::t2STMDB_UPD:
    6661             :     if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
    6662             :       return Error(Operands.back()->getStartLoc(),
    6663             :                    "writeback register not allowed in register list");
    6664             : 
    6665             :     if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD) {
    6666             :       if (validatetLDMRegList(Inst, Operands, 3))
    6667         105 :         return true;
    6668             :     } else {
    6669         166 :       if (validatetSTMRegList(Inst, Operands, 3))
    6670          20 :         return true;
    6671             :     }
    6672             :     break;
    6673          20 : 
    6674             :   case ARM::sysLDMIA_UPD:
    6675          20 :   case ARM::sysLDMDA_UPD:
    6676           2 :   case ARM::sysLDMDB_UPD:
    6677             :   case ARM::sysLDMIB_UPD:
    6678          30 :     if (!listContainsReg(Inst, 3, ARM::PC))
    6679             :       return Error(Operands[4]->getStartLoc(),
    6680          30 :                    "writeback register only allowed on system LDM "
    6681           2 :                    "if PC in register-list");
    6682             :     break;
    6683             :   case ARM::sysSTMIA_UPD:
    6684             :   case ARM::sysSTMDA_UPD:
    6685             :   case ARM::sysSTMDB_UPD:
    6686             :   case ARM::sysSTMIB_UPD:
    6687         118 :     return Error(Operands[2]->getStartLoc(),
    6688           8 :                  "system STM cannot have writeback register");
    6689             :   case ARM::tMUL:
    6690             :     // The second source operand must be the same register as the destination
    6691          55 :     // operand.
    6692          29 :     //
    6693           8 :     // In this case, we must directly check the parsed operands because the
    6694             :     // cvtThumbMultiply() function is written in such a way that it guarantees
    6695          26 :     // this first statement is always true for the new Inst.  Essentially, the
    6696          11 :     // destination is unconditionally copied into the second source operand
    6697             :     // without checking to see if it matches what we actually parsed.
    6698             :     if (Operands.size() == 6 && (((ARMOperand &)*Operands[3]).getReg() !=
    6699             :                                  ((ARMOperand &)*Operands[5]).getReg()) &&
    6700             :         (((ARMOperand &)*Operands[3]).getReg() !=
    6701             :          ((ARMOperand &)*Operands[4]).getReg())) {
    6702             :       return Error(Operands[3]->getStartLoc(),
    6703             :                    "destination register must match source register");
    6704           4 :     }
    6705           4 :     break;
    6706             : 
    6707             :   // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
    6708             :   // so only issue a diagnostic for thumb1. The instructions will be
    6709             :   // switched to the t2 encodings in processInstruction() if necessary.
    6710             :   case ARM::tPOP: {
    6711             :     bool ListContainsBase;
    6712             :     if (checkLowRegisterList(Inst, 2, 0, ARM::PC, ListContainsBase) &&
    6713           4 :         !isThumbTwo())
    6714             :       return Error(Operands[2]->getStartLoc(),
    6715          16 :                    "registers must be in range r0-r7 or pc");
    6716             :     if (validatetLDMRegList(Inst, Operands, 2, !isMClass()))
    6717             :       return true;
    6718             :     break;
    6719             :   }
    6720             :   case ARM::tPUSH: {
    6721             :     bool ListContainsBase;
    6722             :     if (checkLowRegisterList(Inst, 2, 0, ARM::LR, ListContainsBase) &&
    6723             :         !isThumbTwo())
    6724          26 :       return Error(Operands[2]->getStartLoc(),
    6725          23 :                    "registers must be in range r0-r7 or lr");
    6726             :     if (validatetSTMRegList(Inst, Operands, 2))
    6727             :       return true;
    6728           8 :     break;
    6729             :   }
    6730             :   case ARM::tSTMIA_UPD: {
    6731             :     bool ListContainsBase, InvalidLowList;
    6732             :     InvalidLowList = checkLowRegisterList(Inst, 4, Inst.getOperand(0).getReg(),
    6733             :                                           0, ListContainsBase);
    6734             :     if (InvalidLowList && !isThumbTwo())
    6735             :       return Error(Operands[4]->getStartLoc(),
    6736             :                    "registers must be in range r0-r7");
    6737             : 
    6738          70 :     // This would be converted to a 32-bit stm, but that's not valid if the
    6739          24 :     // writeback register is in the list.
    6740           4 :     if (InvalidLowList && ListContainsBase)
    6741             :       return Error(Operands[4]->getStartLoc(),
    6742          44 :                    "writeback operator '!' not allowed when base register "
    6743           6 :                    "in register list");
    6744             : 
    6745             :     if (validatetSTMRegList(Inst, Operands, 4))
    6746             :       return true;
    6747             :     break;
    6748          59 :   }
    6749          16 :   case ARM::tADDrSP:
    6750           4 :     // If the non-SP source operand and the destination operand are not the
    6751             :     // same, we need thumb2 (for the wide encoding), or we have an error.
    6752          41 :     if (!isThumbTwo() &&
    6753           9 :         Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
    6754             :       return Error(Operands[4]->getStartLoc(),
    6755             :                    "source register must be the same as destination");
    6756             :     }
    6757             :     break;
    6758          41 : 
    6759             :   // Final range checking for Thumb unconditional branch instructions.
    6760          33 :   case ARM::tB:
    6761          16 :     if (!(static_cast<ARMOperand &>(*Operands[2])).isSignedOffset<11, 1>())
    6762             :       return Error(Operands[2]->getStartLoc(), "branch target out of range");
    6763             :     break;
    6764             :   case ARM::t2B: {
    6765             :     int op = (Operands[2]->isImm()) ? 2 : 3;
    6766          33 :     if (!static_cast<ARMOperand &>(*Operands[op]).isSignedOffset<24, 1>())
    6767           4 :       return Error(Operands[op]->getStartLoc(), "branch target out of range");
    6768             :     break;
    6769             :   }
    6770             :   // Final range checking for Thumb conditional branch instructions.
    6771          31 :   case ARM::tBcc:
    6772          13 :     if (!static_cast<ARMOperand &>(*Operands[2]).isSignedOffset<8, 1>())
    6773             :       return Error(Operands[2]->getStartLoc(), "branch target out of range");
    6774             :     break;
    6775          18 :   case ARM::t2Bcc: {
    6776             :     int Op = (Operands[2]->isImm()) ? 2 : 3;
    6777             :     if (!static_cast<ARMOperand &>(*Operands[Op]).isSignedOffset<20, 1>())
    6778          18 :       return Error(Operands[Op]->getStartLoc(), "branch target out of range");
    6779           4 :     break;
    6780           4 :   }
    6781             :   case ARM::tCBZ:
    6782             :   case ARM::tCBNZ: {
    6783             :     if (!static_cast<ARMOperand &>(*Operands[2]).isUnsignedOffset<6, 1>())
    6784             :       return Error(Operands[2]->getStartLoc(), "branch target out of range");
    6785             :     break;
    6786         100 :   }
    6787          46 :   case ARM::MOVi16:
    6788          12 :   case ARM::MOVTi16:
    6789             :   case ARM::t2MOVi16:
    6790         102 :   case ARM::t2MOVTi16:
    6791         102 :     {
    6792         166 :     // We want to avoid misleadingly allowing something like "mov r0, <symbol>"
    6793          18 :     // especially when we turn it into a movw and the expression <symbol> does
    6794             :     // not have a :lower16: or :upper16 as part of the expression.  We don't
    6795             :     // want the behavior of silently truncating, which can be unexpected and
    6796             :     // lead to bugs that are difficult to find since this is an easy mistake
    6797          98 :     // to make.
    6798          36 :     int i = (Operands[3]->isImm()) ? 3 : 4;
    6799          12 :     ARMOperand &Op = static_cast<ARMOperand &>(*Operands[i]);
    6800             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
    6801          74 :     if (CE) break;
    6802          74 :     const MCExpr *E = dyn_cast<MCExpr>(Op.getImm());
    6803         123 :     if (!E) break;
    6804          18 :     const ARMMCExpr *ARM16Expr = dyn_cast<ARMMCExpr>(E);
    6805             :     if (!ARM16Expr || (ARM16Expr->getKind() != ARMMCExpr::VK_ARM_HI16 &&
    6806             :                        ARM16Expr->getKind() != ARMMCExpr::VK_ARM_LO16))
    6807          44 :       return Error(
    6808             :           Op.getStartLoc(),
    6809          14 :           "immediate expression for mov requires :lower16: or :upper16");
    6810           8 :     break;
    6811             :   }
    6812             :   case ARM::HINT:
    6813         310 :   case ARM::t2HINT: {
    6814             :     unsigned Imm8 = Inst.getOperand(0).getImm();
    6815             :     unsigned Pred = Inst.getOperand(1).getImm();
    6816             :     // ESB is not predicable (pred must be AL). Without the RAS extension, this
    6817             :     // behaves as any other unallocated hint.
    6818             :     if (Imm8 == 0x10 && Pred != ARMCC::AL && hasRAS())
    6819             :       return Error(Operands[1]->getStartLoc(), "instruction 'esb' is not "
    6820             :                                                "predicable, but condition "
    6821             :                                                "code specified");
    6822             :     if (Imm8 == 0x14 && Pred != ARMCC::AL)
    6823             :       return Error(Operands[1]->getStartLoc(), "instruction 'csdb' is not "
    6824         310 :                                                "predicable, but condition "
    6825         310 :                                                "code specified");
    6826         310 :     break;
    6827             :   }
    6828             :   case ARM::DSB:
    6829             :   case ARM::t2DSB: {
    6830             : 
    6831         191 :     if (Inst.getNumOperands() < 2)
    6832             :       break;
    6833          10 : 
    6834             :     unsigned Option = Inst.getOperand(0).getImm();
    6835             :     unsigned Pred = Inst.getOperand(1).getImm();
    6836             : 
    6837             :     // SSBB and PSSBB (DSB #0|#4) are not predicable (pred must be AL).
    6838             :     if (Option == 0 && Pred != ARMCC::AL)
    6839             :       return Error(Operands[1]->getStartLoc(),
    6840         135 :                    "instruction 'ssbb' is not predicable, but condition code "
    6841         135 :                    "specified");
    6842             :     if (Option == 4 && Pred != ARMCC::AL)
    6843             :       return Error(Operands[1]->getStartLoc(),
    6844         137 :                    "instruction 'pssbb' is not predicable, but condition code "
    6845           0 :                    "specified");
    6846             :     break;
    6847             :   }
    6848         135 :   case ARM::VMOVRRS: {
    6849           8 :     // Source registers must be sequential.
    6850             :     const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(2).getReg());
    6851             :     const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(3).getReg());
    6852             :     if (Sm1 != Sm + 1)
    6853             :       return Error(Operands[5]->getStartLoc(),
    6854             :                    "source operands must be sequential");
    6855             :     break;
    6856             :   }
    6857         148 :   case ARM::VMOVSRR: {
    6858             :     // Destination registers must be sequential.
    6859             :     const unsigned Sm = MRI->getEncodingValue(Inst.getOperand(0).getReg());
    6860          73 :     const unsigned Sm1 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
    6861          73 :     if (Sm1 != Sm + 1)
    6862             :       return Error(Operands[3]->getStartLoc(),
    6863             :                    "destination operands must be sequential");
    6864          73 :     break;
    6865           2 :   }
    6866             :   case ARM::VLDMDIA:
    6867             :   case ARM::VSTMDIA: {
    6868          72 :     ARMOperand &Op = static_cast<ARMOperand&>(*Operands[3]);
    6869           2 :     auto &RegList = Op.getRegList();
    6870             :     if (RegList.size() < 1 || RegList.size() > 16)
    6871             :       return Error(Operands[3]->getStartLoc(),
    6872             :                    "list of registers must be at least 1 and at most 16");
    6873             :     break;
    6874           3 :   }
    6875             :   }
    6876           6 : 
    6877           3 :   return false;
    6878           3 : }
    6879           2 : 
    6880             : static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
    6881             :   switch(Opc) {
    6882             :   default: llvm_unreachable("unexpected opcode!");
    6883           4 :   // VST1LN
    6884             :   case ARM::VST1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
    6885           8 :   case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
    6886           4 :   case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
    6887           4 :   case ARM::VST1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
    6888           2 :   case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
    6889             :   case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
    6890             :   case ARM::VST1LNdAsm_8:  Spacing = 1; return ARM::VST1LNd8;
    6891             :   case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
    6892          15 :   case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
    6893             : 
    6894             :   // VST2LN
    6895             :   case ARM::VST2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
    6896          30 :   case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
    6897           4 :   case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
    6898             :   case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
    6899             :   case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
    6900             : 
    6901             :   case ARM::VST2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
    6902             :   case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
    6903             :   case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
    6904             :   case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
    6905             :   case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
    6906         322 : 
    6907         322 :   case ARM::VST2LNdAsm_8:  Spacing = 1; return ARM::VST2LNd8;
    6908           0 :   case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
    6909             :   case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
    6910           1 :   case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
    6911           2 :   case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
    6912           3 : 
    6913           1 :   // VST3LN
    6914           2 :   case ARM::VST3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
    6915           3 :   case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
    6916           1 :   case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
    6917           2 :   case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
    6918           3 :   case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
    6919             :   case ARM::VST3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
    6920             :   case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
    6921           3 :   case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
    6922           0 :   case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
    6923           2 :   case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
    6924           1 :   case ARM::VST3LNdAsm_8:  Spacing = 1; return ARM::VST3LNd8;
    6925           3 :   case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
    6926             :   case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
    6927           3 :   case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
    6928           0 :   case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
    6929           2 : 
    6930           1 :   // VST3
    6931           3 :   case ARM::VST3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
    6932             :   case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
    6933           5 :   case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
    6934           2 :   case ARM::VST3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
    6935           4 :   case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
    6936           3 :   case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
    6937           5 :   case ARM::VST3dWB_register_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
    6938             :   case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
    6939             :   case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
    6940           2 :   case ARM::VST3qWB_register_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
    6941           2 :   case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
    6942           2 :   case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
    6943           2 :   case ARM::VST3dAsm_8:  Spacing = 1; return ARM::VST3d8;
    6944           2 :   case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
    6945           2 :   case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
    6946           2 :   case ARM::VST3qAsm_8:  Spacing = 2; return ARM::VST3q8;
    6947           2 :   case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
    6948           2 :   case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
    6949           2 : 
    6950           3 :   // VST4LN
    6951           3 :   case ARM::VST4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
    6952           3 :   case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
    6953           3 :   case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
    6954           3 :   case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
    6955             :   case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
    6956             :   case ARM::VST4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
    6957           3 :   case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
    6958           3 :   case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
    6959           3 :   case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
    6960           5 :   case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
    6961           5 :   case ARM::VST4LNdAsm_8:  Spacing = 1; return ARM::VST4LNd8;
    6962           5 :   case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
    6963           3 :   case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
    6964           3 :   case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
    6965           3 :   case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
    6966           3 : 
    6967           3 :   // VST4
    6968           3 :   case ARM::VST4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
    6969           4 :   case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
    6970           4 :   case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
    6971           4 :   case ARM::VST4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
    6972           3 :   case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
    6973           3 :   case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
    6974           3 :   case ARM::VST4dWB_register_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
    6975             :   case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
    6976             :   case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
    6977           3 :   case ARM::VST4qWB_register_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
    6978           3 :   case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
    6979           7 :   case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
    6980           3 :   case ARM::VST4dAsm_8:  Spacing = 1; return ARM::VST4d8;
    6981           7 :   case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
    6982           3 :   case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
    6983           3 :   case ARM::VST4qAsm_8:  Spacing = 2; return ARM::VST4q8;
    6984           7 :   case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
    6985           3 :   case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
    6986           7 :   }
    6987           4 : }
    6988           4 : 
    6989           5 : static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
    6990           4 :   switch(Opc) {
    6991           8 :   default: llvm_unreachable("unexpected opcode!");
    6992             :   // VLD1LN
    6993             :   case ARM::VLD1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
    6994           5 :   case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
    6995           5 :   case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
    6996           5 :   case ARM::VLD1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
    6997           7 :   case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
    6998           7 :   case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
    6999           7 :   case ARM::VLD1LNdAsm_8:  Spacing = 1; return ARM::VLD1LNd8;
    7000           5 :   case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
    7001           5 :   case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
    7002           5 : 
    7003           5 :   // VLD2LN
    7004           5 :   case ARM::VLD2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
    7005           5 :   case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
    7006           6 :   case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
    7007           6 :   case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
    7008           5 :   case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
    7009           5 :   case ARM::VLD2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
    7010           5 :   case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
    7011           5 :   case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
    7012             :   case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
    7013             :   case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
    7014             :   case ARM::VLD2LNdAsm_8:  Spacing = 1; return ARM::VLD2LNd8;
    7015         424 :   case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
    7016         424 :   case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
    7017           0 :   case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
    7018             :   case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
    7019           2 : 
    7020           3 :   // VLD3DUP
    7021           4 :   case ARM::VLD3DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
    7022           2 :   case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
    7023           3 :   case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
    7024           4 :   case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
    7025           3 :   case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
    7026           4 :   case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
    7027           6 :   case ARM::VLD3DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
    7028             :   case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
    7029             :   case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
    7030           3 :   case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
    7031           2 :   case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
    7032           2 :   case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
    7033           2 :   case ARM::VLD3DUPdAsm_8:  Spacing = 1; return ARM::VLD3DUPd8;
    7034           3 :   case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
    7035           3 :   case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
    7036           2 :   case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
    7037           2 :   case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
    7038           2 :   case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
    7039           2 : 
    7040           5 :   // VLD3LN
    7041           4 :   case ARM::VLD3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
    7042           4 :   case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
    7043           4 :   case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
    7044           4 :   case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
    7045             :   case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
    7046             :   case ARM::VLD3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
    7047           2 :   case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
    7048           2 :   case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
    7049           2 :   case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
    7050           2 :   case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
    7051           2 :   case ARM::VLD3LNdAsm_8:  Spacing = 1; return ARM::VLD3LNd8;
    7052           2 :   case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
    7053           2 :   case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
    7054           2 :   case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
    7055           2 :   case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
    7056           2 : 
    7057           2 :   // VLD3
    7058           2 :   case ARM::VLD3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
    7059           2 :   case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
    7060           2 :   case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
    7061           2 :   case ARM::VLD3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
    7062           2 :   case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
    7063           2 :   case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
    7064           2 :   case ARM::VLD3dWB_register_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
    7065             :   case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
    7066             :   case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
    7067           2 :   case ARM::VLD3qWB_register_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
    7068           2 :   case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
    7069           2 :   case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
    7070           2 :   case ARM::VLD3dAsm_8:  Spacing = 1; return ARM::VLD3d8;
    7071           2 :   case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
    7072           2 :   case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
    7073           2 :   case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;
    7074           2 :   case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
    7075           2 :   case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
    7076           2 : 
    7077           3 :   // VLD4LN
    7078           3 :   case ARM::VLD4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
    7079           3 :   case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
    7080           3 :   case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
    7081           3 :   case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
    7082             :   case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
    7083             :   case ARM::VLD4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
    7084           3 :   case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
    7085           3 :   case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
    7086           3 :   case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
    7087           5 :   case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
    7088           5 :   case ARM::VLD4LNdAsm_8:  Spacing = 1; return ARM::VLD4LNd8;
    7089           5 :   case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
    7090           3 :   case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
    7091           3 :   case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
    7092           3 :   case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
    7093           3 : 
    7094           3 :   // VLD4DUP
    7095           3 :   case ARM::VLD4DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
    7096           4 :   case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
    7097           4 :   case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
    7098           4 :   case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
    7099           3 :   case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
    7100           3 :   case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
    7101           3 :   case ARM::VLD4DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
    7102             :   case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
    7103             :   case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
    7104           3 :   case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
    7105           3 :   case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
    7106           4 :   case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
    7107           3 :   case ARM::VLD4DUPdAsm_8:  Spacing = 1; return ARM::VLD4DUPd8;
    7108           4 :   case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
    7109           3 :   case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
    7110           3 :   case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
    7111           4 :   case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
    7112           3 :   case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
    7113           4 : 
    7114           4 :   // VLD4
    7115           4 :   case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
    7116           5 :   case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
    7117           4 :   case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
    7118           5 :   case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
    7119             :   case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
    7120             :   case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
    7121           3 :   case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
    7122           3 :   case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
    7123           4 :   case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
    7124           3 :   case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
    7125           3 :   case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
    7126           4 :   case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
    7127           3 :   case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8;
    7128           3 :   case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
    7129           4 :   case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
    7130           3 :   case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8;
    7131           3 :   case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
    7132           4 :   case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
    7133           3 :   }
    7134           3 : }
    7135           4 : 
    7136           3 : bool ARMAsmParser::processInstruction(MCInst &Inst,
    7137           3 :                                       const OperandVector &Operands,
    7138           4 :                                       MCStreamer &Out) {
    7139             :   // Check if we have the wide qualifier, because if it's present we
    7140             :   // must avoid selecting a 16-bit thumb instruction.
    7141           5 :   bool HasWideQualifier = false;
    7142           5 :   for (auto &Op : Operands) {
    7143           5 :     ARMOperand &ARMOp = static_cast<ARMOperand&>(*Op);
    7144           7 :     if (ARMOp.isToken() && ARMOp.getToken() == ".w") {
    7145           7 :       HasWideQualifier = true;
    7146           7 :       break;
    7147           5 :     }
    7148           5 :   }
    7149           5 : 
    7150           5 :   switch (Inst.getOpcode()) {
    7151           5 :   // Alias for alternate form of 'ldr{,b}t Rt, [Rn], #imm' instruction.
    7152           5 :   case ARM::LDRT_POST:
    7153           6 :   case ARM::LDRBT_POST: {
    7154           6 :     const unsigned Opcode =
    7155           6 :       (Inst.getOpcode() == ARM::LDRT_POST) ? ARM::LDRT_POST_IMM
    7156           5 :                                            : ARM::LDRBT_POST_IMM;
    7157           5 :     MCInst TmpInst;
    7158           5 :     TmpInst.setOpcode(Opcode);
    7159             :     TmpInst.addOperand(Inst.getOperand(0));
    7160             :     TmpInst.addOperand(Inst.getOperand(1));
    7161             :     TmpInst.addOperand(Inst.getOperand(1));
    7162       22359 :     TmpInst.addOperand(MCOperand::createReg(0));
    7163             :     TmpInst.addOperand(MCOperand::createImm(0));
    7164             :     TmpInst.addOperand(Inst.getOperand(2));
    7165             :     TmpInst.addOperand(Inst.getOperand(3));
    7166             :     Inst = TmpInst;
    7167             :     return true;
    7168      123535 :   }
    7169             :   // Alias for alternate form of 'str{,b}t Rt, [Rn], #imm' instruction.
    7170      102361 :   case ARM::STRT_POST:
    7171             :   case ARM::STRBT_POST: {
    7172             :     const unsigned Opcode =
    7173             :       (Inst.getOpcode() == ARM::STRT_POST) ? ARM::STRT_POST_IMM
    7174             :                                            : ARM::STRBT_POST_IMM;
    7175             :     MCInst TmpInst;
    7176       22359 :     TmpInst.setOpcode(Opcode);
    7177             :     TmpInst.addOperand(Inst.getOperand(1));
    7178           2 :     TmpInst.addOperand(Inst.getOperand(0));
    7179             :     TmpInst.addOperand(Inst.getOperand(1));
    7180             :     TmpInst.addOperand(MCOperand::createReg(0));
    7181           2 :     TmpInst.addOperand(MCOperand::createImm(0));
    7182             :     TmpInst.addOperand(Inst.getOperand(2));
    7183             :     TmpInst.addOperand(Inst.getOperand(3));
    7184             :     Inst = TmpInst;
    7185             :     return true;
    7186             :   }
    7187             :   // Alias for alternate form of 'ADR Rd, #imm' instruction.
    7188           2 :   case ARM::ADDri: {
    7189           2 :     if (Inst.getOperand(1).getReg() != ARM::PC ||
    7190             :         Inst.getOperand(5).getReg() != 0 ||
    7191             :         !(Inst.getOperand(2).isExpr() || Inst.getOperand(2).isImm()))
    7192             :       return false;
    7193             :     MCInst TmpInst;
    7194             :     TmpInst.setOpcode(ARM::ADR);
    7195             :     TmpInst.addOperand(Inst.getOperand(0));
    7196           4 :     if (Inst.getOperand(2).isImm()) {
    7197             :       // Immediate (mod_imm) will be in its encoded form, we must unencode it
    7198             :       // before passing it to the ADR instruction.
    7199           4 :       unsigned Enc = Inst.getOperand(2).getImm();
    7200             :       TmpInst.addOperand(MCOperand::createImm(
    7201             :         ARM_AM::rotr32(Enc & 0xFF, (Enc & 0xF00) >> 7)));
    7202             :     } else {
    7203             :       // Turn PC-relative expression into absolute expression.
    7204             :       // Reading PC provides the start of the current instruction + 8 and
    7205             :       // the transform to adr is biased by that.
    7206           4 :       MCSymbol *Dot = getContext().createTempSymbol();
    7207           4 :       Out.EmitLabel(Dot);
    7208             :       const MCExpr *OpExpr = Inst.getOperand(2).getExpr();
    7209             :       const MCExpr *InstPC = MCSymbolRefExpr::create(Dot,
    7210             :                                                      MCSymbolRefExpr::VK_None,
    7211             :                                                      getContext());
    7212             :       const MCExpr *Const8 = MCConstantExpr::create(8, getContext());
    7213             :       const MCExpr *ReadPC = MCBinaryExpr::createAdd(InstPC, Const8,
    7214             :                                                      getContext());
    7215         370 :       const MCExpr *FixupAddr = MCBinaryExpr::createAdd(ReadPC, OpExpr,
    7216         363 :                                                         getContext());
    7217           5 :       TmpInst.addOperand(MCOperand::createExpr(FixupAddr));
    7218             :     }
    7219             :     TmpInst.addOperand(Inst.getOperand(3));
    7220             :     TmpInst.addOperand(Inst.getOperand(4));
    7221             :     Inst = TmpInst;
    7222           5 :     return true;
    7223             :   }
    7224             :   // Aliases for alternate PC+imm syntax of LDR instructions.
    7225           3 :   case ARM::t2LDRpcrel:
    7226           3 :     // Select the narrow version if the immediate will fit.
    7227           6 :     if (Inst.getOperand(1).getImm() > 0 &&
    7228             :         Inst.getOperand(1).getImm() <= 0xff &&
    7229             :         !HasWideQualifier)
    7230             :       Inst.setOpcode(ARM::tLDRpci);
    7231             :     else
    7232           2 :       Inst.setOpcode(ARM::t2LDRpci);
    7233           2 :     return true;
    7234           2 :   case ARM::t2LDRBpcrel:
    7235           2 :     Inst.setOpcode(ARM::t2LDRBpci);
    7236             :     return true;
    7237           2 :   case ARM::t2LDRHpcrel:
    7238           2 :     Inst.setOpcode(ARM::t2LDRHpci);
    7239             :     return true;
    7240             :   case ARM::t2LDRSBpcrel:
    7241             :     Inst.setOpcode(ARM::t2LDRSBpci);
    7242             :     return true;
    7243           2 :   case ARM::t2LDRSHpcrel:
    7244             :     Inst.setOpcode(ARM::t2LDRSHpci);
    7245             :     return true;
    7246             :   case ARM::LDRConstPool:
    7247             :   case ARM::tLDRConstPool:
    7248             :   case ARM::t2LDRConstPool: {
    7249             :     // Pseudo instruction ldr rt, =immediate is converted to a
    7250             :     // MOV rt, immediate if immediate is known and representable
    7251             :     // otherwise we create a constant pool entry that we load from.
    7252             :     MCInst TmpInst;
    7253           0 :     if (Inst.getOpcode() == ARM::LDRConstPool)
    7254          18 :       TmpInst.setOpcode(ARM::LDRi12);
    7255             :     else if (Inst.getOpcode() == ARM::tLDRConstPool)
    7256             :       TmpInst.setOpcode(ARM::tLDRpci);
    7257             :     else if (Inst.getOpcode() == ARM::t2LDRConstPool)
    7258             :       TmpInst.setOpcode(ARM::t2LDRpci);
    7259             :     const ARMOperand &PoolOperand =
    7260             :       (HasWideQualifier ?
    7261             :        static_cast<ARMOperand &>(*Operands[4]) :
    7262           7 :        static_cast<ARMOperand &>(*Operands[3]));
    7263             :     const MCExpr *SubExprVal = PoolOperand.getConstantPoolImm();
    7264             :     // If SubExprVal is a constant we may be able to use a MOV
    7265           7 :     if (isa<MCConstantExpr>(SubExprVal) &&
    7266             :         Inst.getOperand(0).getReg() != ARM::PC &&
    7267             :         Inst.getOperand(0).getReg() != ARM::SP) {
    7268           7 :       int64_t Value =
    7269             :         (int64_t) (cast<MCConstantExpr>(SubExprVal))->getValue();
    7270             :       bool UseMov  = true;
    7271           7 :       bool MovHasS = true;
    7272             :       if (Inst.getOpcode() == ARM::LDRConstPool) {
    7273             :         // ARM Constant
    7274             :         if (ARM_AM::getSOImmVal(Value) != -1) {
    7275             :           Value = ARM_AM::getSOImmVal(Value);
    7276             :           TmpInst.setOpcode(ARM::MOVi);
    7277             :         }
    7278             :         else if (ARM_AM::getSOImmVal(~Value) != -1) {
    7279         378 :           Value = ARM_AM::getSOImmVal(~Value);
    7280             :           TmpInst.setOpcode(ARM::MVNi);
    7281         221 :         }
    7282             :         else if (hasV6T2Ops() &&
    7283          10 :                  Value >=0 && Value < 65536) {
    7284             :           TmpInst.setOpcode(ARM::MOVi16);
    7285             :           MovHasS = false;
    7286             :         }
    7287             :         else
    7288         378 :           UseMov = false;
    7289         378 :       }
    7290             :       else {
    7291         298 :         // Thumb/Thumb2 Constant
    7292         378 :         if (hasThumb2() &&
    7293             :             ARM_AM::getT2SOImmVal(Value) != -1)
    7294             :           TmpInst.setOpcode(ARM::t2MOVi);
    7295         290 :         else if (hasThumb2() &&
    7296             :                  ARM_AM::getT2SOImmVal(~Value) != -1) {
    7297             :           TmpInst.setOpcode(ARM::t2MVNi);
    7298         290 :           Value = ~Value;
    7299             :         }
    7300         121 :         else if (hasV8MBaseline() &&
    7301          34 :                  Value >=0 && Value < 65536) {
    7302             :           TmpInst.setOpcode(ARM::t2MOVi16);
    7303             :           MovHasS = false;
    7304          87 :         }
    7305           8 :         else
    7306             :           UseMov = false;
    7307             :       }
    7308             :       if (UseMov) {
    7309          79 :         TmpInst.addOperand(Inst.getOperand(0));           // Rt
    7310             :         TmpInst.addOperand(MCOperand::createImm(Value));  // Immediate
    7311             :         TmpInst.addOperand(Inst.getOperand(2));           // CondCode
    7312             :         TmpInst.addOperand(Inst.getOperand(3));           // CondCode
    7313             :         if (MovHasS)
    7314             :           TmpInst.addOperand(MCOperand::createReg(0));    // S
    7315             :         Inst = TmpInst;
    7316             :         return true;
    7317             :       }
    7318         169 :     }
    7319          72 :     // No opportunity to use MOV/MVN create constant pool
    7320             :     const MCExpr *CPLoc =
    7321         147 :       getTargetStreamer().addConstantPoolEntry(SubExprVal,
    7322          50 :                                                PoolOperand.getStartLoc());
    7323             :     TmpInst.addOperand(Inst.getOperand(0));           // Rt
    7324           2 :     TmpInst.addOperand(MCOperand::createExpr(CPLoc)); // offset to constpool
    7325             :     if (TmpInst.getOpcode() == ARM::LDRi12)
    7326             :       TmpInst.addOperand(MCOperand::createImm(0));    // unused offset
    7327         145 :     TmpInst.addOperand(Inst.getOperand(2));           // CondCode
    7328             :     TmpInst.addOperand(Inst.getOperand(3));           // CondCode
    7329             :     Inst = TmpInst;
    7330             :     return true;
    7331             :   }
    7332             :   // Handle NEON VST complex aliases.
    7333             :   case ARM::VST1LNdWB_register_Asm_8:
    7334         290 :   case ARM::VST1LNdWB_register_Asm_16:
    7335             :   case ARM::VST1LNdWB_register_Asm_32: {
    7336          86 :     MCInst TmpInst;
    7337             :     // Shuffle the operands around so the lane index operand is in the
    7338             :     // right place.
    7339          86 :     unsigned Spacing;
    7340          66 :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7341             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7342          86 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7343             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7344             :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7345             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7346             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7347         292 :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7348             :     TmpInst.addOperand(Inst.getOperand(6));
    7349             :     Inst = TmpInst;
    7350         292 :     return true;
    7351         292 :   }
    7352         111 : 
    7353             :   case ARM::VST2LNdWB_register_Asm_8:
    7354             :   case ARM::VST2LNdWB_register_Asm_16:
    7355             :   case ARM::VST2LNdWB_register_Asm_32:
    7356         292 :   case ARM::VST2LNqWB_register_Asm_16:
    7357             :   case ARM::VST2LNqWB_register_Asm_32: {
    7358             :     MCInst TmpInst;
    7359             :     // Shuffle the operands around so the lane index operand is in the
    7360             :     // right place.
    7361             :     unsigned Spacing;
    7362             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7363             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7364             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7365             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7366           6 :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7367             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7368             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7369             :                                             Spacing));
    7370             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7371             :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7372             :     TmpInst.addOperand(Inst.getOperand(6));
    7373             :     Inst = TmpInst;
    7374             :     return true;
    7375             :   }
    7376             : 
    7377             :   case ARM::VST3LNdWB_register_Asm_8:
    7378             :   case ARM::VST3LNdWB_register_Asm_16:
    7379             :   case ARM::VST3LNdWB_register_Asm_32:
    7380             :   case ARM::VST3LNqWB_register_Asm_16:
    7381             :   case ARM::VST3LNqWB_register_Asm_32: {
    7382             :     MCInst TmpInst;
    7383             :     // Shuffle the operands around so the lane index operand is in the
    7384             :     // right place.
    7385             :     unsigned Spacing;
    7386             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7387             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7388           9 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7389             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7390             :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7391             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7392             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7393             :                                             Spacing));
    7394           9 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7395          18 :                                             Spacing * 2));
    7396             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7397             :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7398             :     TmpInst.addOperand(Inst.getOperand(6));
    7399             :     Inst = TmpInst;
    7400             :     return true;
    7401             :   }
    7402             : 
    7403             :   case ARM::VST4LNdWB_register_Asm_8:
    7404             :   case ARM::VST4LNdWB_register_Asm_16:
    7405             :   case ARM::VST4LNdWB_register_Asm_32:
    7406             :   case ARM::VST4LNqWB_register_Asm_16:
    7407             :   case ARM::VST4LNqWB_register_Asm_32: {
    7408             :     MCInst TmpInst;
    7409             :     // Shuffle the operands around so the lane index operand is in the
    7410             :     // right place.
    7411             :     unsigned Spacing;
    7412          10 :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7413             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7414             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7415             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7416             :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7417             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7418          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7419          20 :                                             Spacing));
    7420          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7421          20 :                                             Spacing * 2));
    7422             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7423             :                                             Spacing * 3));
    7424             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7425             :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7426             :     TmpInst.addOperand(Inst.getOperand(6));
    7427             :     Inst = TmpInst;
    7428             :     return true;
    7429             :   }
    7430             : 
    7431             :   case ARM::VST1LNdWB_fixed_Asm_8:
    7432             :   case ARM::VST1LNdWB_fixed_Asm_16:
    7433             :   case ARM::VST1LNdWB_fixed_Asm_32: {
    7434             :     MCInst TmpInst;
    7435             :     // Shuffle the operands around so the lane index operand is in the
    7436             :     // right place.
    7437             :     unsigned Spacing;
    7438          23 :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7439             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7440             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7441             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7442             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7443             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7444          23 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7445          46 :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7446          23 :     TmpInst.addOperand(Inst.getOperand(5));
    7447          46 :     Inst = TmpInst;
    7448          23 :     return true;
    7449          46 :   }
    7450             : 
    7451             :   case ARM::VST2LNdWB_fixed_Asm_8:
    7452             :   case ARM::VST2LNdWB_fixed_Asm_16:
    7453             :   case ARM::VST2LNdWB_fixed_Asm_32:
    7454             :   case ARM::VST2LNqWB_fixed_Asm_16:
    7455             :   case ARM::VST2LNqWB_fixed_Asm_32: {
    7456             :     MCInst TmpInst;
    7457             :     // Shuffle the operands around so the lane index operand is in the
    7458             :     // right place.
    7459             :     unsigned Spacing;
    7460             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7461             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7462             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7463             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7464           6 :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7465             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7466             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7467             :                                             Spacing));
    7468           6 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7469             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7470             :     TmpInst.addOperand(Inst.getOperand(5));
    7471             :     Inst = TmpInst;
    7472             :     return true;
    7473             :   }
    7474             : 
    7475             :   case ARM::VST3LNdWB_fixed_Asm_8:
    7476             :   case ARM::VST3LNdWB_fixed_Asm_16:
    7477             :   case ARM::VST3LNdWB_fixed_Asm_32:
    7478             :   case ARM::VST3LNqWB_fixed_Asm_16:
    7479             :   case ARM::VST3LNqWB_fixed_Asm_32: {
    7480             :     MCInst TmpInst;
    7481             :     // Shuffle the operands around so the lane index operand is in the
    7482             :     // right place.
    7483             :     unsigned Spacing;
    7484             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7485             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7486           9 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7487             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7488             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7489             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7490           9 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7491             :                                             Spacing));
    7492           9 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7493          18 :                                             Spacing * 2));
    7494             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7495             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7496             :     TmpInst.addOperand(Inst.getOperand(5));
    7497             :     Inst = TmpInst;
    7498             :     return true;
    7499             :   }
    7500             : 
    7501             :   case ARM::VST4LNdWB_fixed_Asm_8:
    7502             :   case ARM::VST4LNdWB_fixed_Asm_16:
    7503             :   case ARM::VST4LNdWB_fixed_Asm_32:
    7504             :   case ARM::VST4LNqWB_fixed_Asm_16:
    7505             :   case ARM::VST4LNqWB_fixed_Asm_32: {
    7506             :     MCInst TmpInst;
    7507             :     // Shuffle the operands around so the lane index operand is in the
    7508             :     // right place.
    7509             :     unsigned Spacing;
    7510          10 :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7511             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7512             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7513             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7514          10 :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7515             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7516          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7517          20 :                                             Spacing));
    7518          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7519          20 :                                             Spacing * 2));
    7520             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7521             :                                             Spacing * 3));
    7522             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7523             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7524             :     TmpInst.addOperand(Inst.getOperand(5));
    7525             :     Inst = TmpInst;
    7526             :     return true;
    7527             :   }
    7528             : 
    7529             :   case ARM::VST1LNdAsm_8:
    7530             :   case ARM::VST1LNdAsm_16:
    7531             :   case ARM::VST1LNdAsm_32: {
    7532             :     MCInst TmpInst;
    7533             :     // Shuffle the operands around so the lane index operand is in the
    7534             :     // right place.
    7535             :     unsigned Spacing;
    7536          23 :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7537             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7538             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7539             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7540          23 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7541             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7542          23 :     TmpInst.addOperand(Inst.getOperand(5));
    7543          46 :     Inst = TmpInst;
    7544          23 :     return true;
    7545          46 :   }
    7546          23 : 
    7547          46 :   case ARM::VST2LNdAsm_8:
    7548             :   case ARM::VST2LNdAsm_16:
    7549             :   case ARM::VST2LNdAsm_32:
    7550             :   case ARM::VST2LNqAsm_16:
    7551             :   case ARM::VST2LNqAsm_32: {
    7552             :     MCInst TmpInst;
    7553             :     // Shuffle the operands around so the lane index operand is in the
    7554             :     // right place.
    7555             :     unsigned Spacing;
    7556             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7557             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7558             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7559             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7560             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7561             :                                             Spacing));
    7562           6 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7563             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7564             :     TmpInst.addOperand(Inst.getOperand(5));
    7565             :     Inst = TmpInst;
    7566             :     return true;
    7567             :   }
    7568             : 
    7569             :   case ARM::VST3LNdAsm_8:
    7570             :   case ARM::VST3LNdAsm_16:
    7571             :   case ARM::VST3LNdAsm_32:
    7572             :   case ARM::VST3LNqAsm_16:
    7573             :   case ARM::VST3LNqAsm_32: {
    7574             :     MCInst TmpInst;
    7575             :     // Shuffle the operands around so the lane index operand is in the
    7576             :     // right place.
    7577             :     unsigned Spacing;
    7578             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7579             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7580             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7581             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7582          19 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7583             :                                             Spacing));
    7584             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7585             :                                             Spacing * 2));
    7586          19 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7587          38 :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7588             :     TmpInst.addOperand(Inst.getOperand(5));
    7589             :     Inst = TmpInst;
    7590             :     return true;
    7591             :   }
    7592             : 
    7593             :   case ARM::VST4LNdAsm_8:
    7594             :   case ARM::VST4LNdAsm_16:
    7595             :   case ARM::VST4LNdAsm_32:
    7596             :   case ARM::VST4LNqAsm_16:
    7597             :   case ARM::VST4LNqAsm_32: {
    7598             :     MCInst TmpInst;
    7599             :     // Shuffle the operands around so the lane index operand is in the
    7600             :     // right place.
    7601             :     unsigned Spacing;
    7602             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    7603             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7604          15 :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7605             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7606             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7607             :                                             Spacing));
    7608          15 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7609          30 :                                             Spacing * 2));
    7610          15 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7611          30 :                                             Spacing * 3));
    7612             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7613             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7614             :     TmpInst.addOperand(Inst.getOperand(5));
    7615             :     Inst = TmpInst;
    7616             :     return true;
    7617             :   }
    7618             : 
    7619             :   // Handle NEON VLD complex aliases.
    7620             :   case ARM::VLD1LNdWB_register_Asm_8:
    7621             :   case ARM::VLD1LNdWB_register_Asm_16:
    7622             :   case ARM::VLD1LNdWB_register_Asm_32: {
    7623             :     MCInst TmpInst;
    7624             :     // Shuffle the operands around so the lane index operand is in the
    7625             :     // right place.
    7626             :     unsigned Spacing;
    7627             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7628          25 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7629             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7630             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7631             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7632          25 :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7633          50 :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7634          25 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7635          50 :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7636          25 :     TmpInst.addOperand(Inst.getOperand(6));
    7637          50 :     Inst = TmpInst;
    7638             :     return true;
    7639             :   }
    7640             : 
    7641             :   case ARM::VLD2LNdWB_register_Asm_8:
    7642             :   case ARM::VLD2LNdWB_register_Asm_16:
    7643             :   case ARM::VLD2LNdWB_register_Asm_32:
    7644             :   case ARM::VLD2LNqWB_register_Asm_16:
    7645             :   case ARM::VLD2LNqWB_register_Asm_32: {
    7646             :     MCInst TmpInst;
    7647             :     // Shuffle the operands around so the lane index operand is in the
    7648             :     // right place.
    7649             :     unsigned Spacing;
    7650             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7651             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7652             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7653           9 :                                             Spacing));
    7654             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7655             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7656             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7657             :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7658             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7659             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7660             :                                             Spacing));
    7661             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7662             :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7663             :     TmpInst.addOperand(Inst.getOperand(6));
    7664             :     Inst = TmpInst;
    7665             :     return true;
    7666             :   }
    7667             : 
    7668             :   case ARM::VLD3LNdWB_register_Asm_8:
    7669             :   case ARM::VLD3LNdWB_register_Asm_16:
    7670             :   case ARM::VLD3LNdWB_register_Asm_32:
    7671             :   case ARM::VLD3LNqWB_register_Asm_16:
    7672             :   case ARM::VLD3LNqWB_register_Asm_32: {
    7673             :     MCInst TmpInst;
    7674             :     // Shuffle the operands around so the lane index operand is in the
    7675             :     // right place.
    7676          11 :     unsigned Spacing;
    7677             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7678          11 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7679          22 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7680             :                                             Spacing));
    7681             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7682             :                                             Spacing * 2));
    7683             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7684             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7685          11 :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7686          22 :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7687             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7688             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7689             :                                             Spacing));
    7690             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7691             :                                             Spacing * 2));
    7692             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7693             :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7694             :     TmpInst.addOperand(Inst.getOperand(6));
    7695             :     Inst = TmpInst;
    7696             :     return true;
    7697             :   }
    7698             : 
    7699             :   case ARM::VLD4LNdWB_register_Asm_8:
    7700             :   case ARM::VLD4LNdWB_register_Asm_16:
    7701             :   case ARM::VLD4LNdWB_register_Asm_32:
    7702             :   case ARM::VLD4LNqWB_register_Asm_16:
    7703          10 :   case ARM::VLD4LNqWB_register_Asm_32: {
    7704             :     MCInst TmpInst;
    7705          10 :     // Shuffle the operands around so the lane index operand is in the
    7706          20 :     // right place.
    7707          10 :     unsigned Spacing;
    7708          20 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7709             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7710             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7711             :                                             Spacing));
    7712             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7713             :                                             Spacing * 2));
    7714          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7715          20 :                                             Spacing * 3));
    7716          10 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7717          20 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7718             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7719             :     TmpInst.addOperand(Inst.getOperand(4)); // Rm
    7720             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7721             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7722             :                                             Spacing));
    7723             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7724             :                                             Spacing * 2));
    7725             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7726             :                                             Spacing * 3));
    7727             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7728             :     TmpInst.addOperand(Inst.getOperand(5)); // CondCode
    7729             :     TmpInst.addOperand(Inst.getOperand(6));
    7730             :     Inst = TmpInst;
    7731             :     return true;
    7732             :   }
    7733             : 
    7734          17 :   case ARM::VLD1LNdWB_fixed_Asm_8:
    7735             :   case ARM::VLD1LNdWB_fixed_Asm_16:
    7736          17 :   case ARM::VLD1LNdWB_fixed_Asm_32: {
    7737          34 :     MCInst TmpInst;
    7738          17 :     // Shuffle the operands around so the lane index operand is in the
    7739          34 :     // right place.
    7740          17 :     unsigned Spacing;
    7741          34 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7742             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7743             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7744             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7745             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7746             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7747          17 :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7748          34 :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7749          17 :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7750          34 :     TmpInst.addOperand(Inst.getOperand(5));
    7751          17 :     Inst = TmpInst;
    7752          34 :     return true;
    7753             :   }
    7754             : 
    7755             :   case ARM::VLD2LNdWB_fixed_Asm_8:
    7756             :   case ARM::VLD2LNdWB_fixed_Asm_16:
    7757             :   case ARM::VLD2LNdWB_fixed_Asm_32:
    7758             :   case ARM::VLD2LNqWB_fixed_Asm_16:
    7759             :   case ARM::VLD2LNqWB_fixed_Asm_32: {
    7760             :     MCInst TmpInst;
    7761             :     // Shuffle the operands around so the lane index operand is in the
    7762             :     // right place.
    7763             :     unsigned Spacing;
    7764             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7765             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7766             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7767           9 :                                             Spacing));
    7768             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7769             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7770             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7771             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7772           9 :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7773             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7774             :                                             Spacing));
    7775             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7776             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7777             :     TmpInst.addOperand(Inst.getOperand(5));
    7778             :     Inst = TmpInst;
    7779             :     return true;
    7780             :   }
    7781             : 
    7782             :   case ARM::VLD3LNdWB_fixed_Asm_8:
    7783             :   case ARM::VLD3LNdWB_fixed_Asm_16:
    7784             :   case ARM::VLD3LNdWB_fixed_Asm_32:
    7785             :   case ARM::VLD3LNqWB_fixed_Asm_16:
    7786             :   case ARM::VLD3LNqWB_fixed_Asm_32: {
    7787             :     MCInst TmpInst;
    7788             :     // Shuffle the operands around so the lane index operand is in the
    7789             :     // right place.
    7790          12 :     unsigned Spacing;
    7791             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7792          12 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7793          24 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7794             :                                             Spacing));
    7795             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7796             :                                             Spacing * 2));
    7797          12 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7798             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7799          12 :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7800          24 :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7801             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7802             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7803             :                                             Spacing));
    7804             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7805             :                                             Spacing * 2));
    7806             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7807             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7808             :     TmpInst.addOperand(Inst.getOperand(5));
    7809             :     Inst = TmpInst;
    7810             :     return true;
    7811             :   }
    7812             : 
    7813             :   case ARM::VLD4LNdWB_fixed_Asm_8:
    7814             :   case ARM::VLD4LNdWB_fixed_Asm_16:
    7815             :   case ARM::VLD4LNdWB_fixed_Asm_32:
    7816             :   case ARM::VLD4LNqWB_fixed_Asm_16:
    7817          10 :   case ARM::VLD4LNqWB_fixed_Asm_32: {
    7818             :     MCInst TmpInst;
    7819          10 :     // Shuffle the operands around so the lane index operand is in the
    7820          20 :     // right place.
    7821          10 :     unsigned Spacing;
    7822          20 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7823             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7824             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7825             :                                             Spacing));
    7826          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7827             :                                             Spacing * 2));
    7828          10 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7829          20 :                                             Spacing * 3));
    7830          10 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
    7831          20 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7832             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7833             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7834             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7835             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7836             :                                             Spacing));
    7837             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7838             :                                             Spacing * 2));
    7839             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7840             :                                             Spacing * 3));
    7841             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7842             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7843             :     TmpInst.addOperand(Inst.getOperand(5));
    7844             :     Inst = TmpInst;
    7845             :     return true;
    7846             :   }
    7847             : 
    7848          17 :   case ARM::VLD1LNdAsm_8:
    7849             :   case ARM::VLD1LNdAsm_16:
    7850          17 :   case ARM::VLD1LNdAsm_32: {
    7851          34 :     MCInst TmpInst;
    7852          17 :     // Shuffle the operands around so the lane index operand is in the
    7853          34 :     // right place.
    7854          17 :     unsigned Spacing;
    7855          34 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7856             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7857             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7858             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7859          17 :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7860             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7861          17 :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7862          34 :     TmpInst.addOperand(Inst.getOperand(5));
    7863          17 :     Inst = TmpInst;
    7864          34 :     return true;
    7865          17 :   }
    7866          34 : 
    7867             :   case ARM::VLD2LNdAsm_8:
    7868             :   case ARM::VLD2LNdAsm_16:
    7869             :   case ARM::VLD2LNdAsm_32:
    7870             :   case ARM::VLD2LNqAsm_16:
    7871             :   case ARM::VLD2LNqAsm_32: {
    7872             :     MCInst TmpInst;
    7873             :     // Shuffle the operands around so the lane index operand is in the
    7874             :     // right place.
    7875             :     unsigned Spacing;
    7876             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7877             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7878             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7879             :                                             Spacing));
    7880             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7881          13 :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7882             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7883             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7884             :                                             Spacing));
    7885             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7886             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7887             :     TmpInst.addOperand(Inst.getOperand(5));
    7888             :     Inst = TmpInst;
    7889             :     return true;
    7890             :   }
    7891             : 
    7892             :   case ARM::VLD3LNdAsm_8:
    7893             :   case ARM::VLD3LNdAsm_16:
    7894             :   case ARM::VLD3LNdAsm_32:
    7895             :   case ARM::VLD3LNqAsm_16:
    7896             :   case ARM::VLD3LNqAsm_32: {
    7897             :     MCInst TmpInst;
    7898             :     // Shuffle the operands around so the lane index operand is in the
    7899             :     // right place.
    7900             :     unsigned Spacing;
    7901             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7902          21 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7903             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7904          21 :                                             Spacing));
    7905          42 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7906             :                                             Spacing * 2));
    7907             :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7908             :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7909          21 :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7910          42 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7911             :                                             Spacing));
    7912             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7913             :                                             Spacing * 2));
    7914             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7915             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7916             :     TmpInst.addOperand(Inst.getOperand(5));
    7917             :     Inst = TmpInst;
    7918             :     return true;
    7919             :   }
    7920             : 
    7921             :   case ARM::VLD4LNdAsm_8:
    7922             :   case ARM::VLD4LNdAsm_16:
    7923             :   case ARM::VLD4LNdAsm_32:
    7924             :   case ARM::VLD4LNqAsm_16:
    7925             :   case ARM::VLD4LNqAsm_32: {
    7926             :     MCInst TmpInst;
    7927          15 :     // Shuffle the operands around so the lane index operand is in the
    7928             :     // right place.
    7929          15 :     unsigned Spacing;
    7930          30 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7931          15 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7932          30 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7933             :                                             Spacing));
    7934             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7935             :                                             Spacing * 2));
    7936          15 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7937          30 :                                             Spacing * 3));
    7938          15 :     TmpInst.addOperand(Inst.getOperand(2)); // Rn
    7939          30 :     TmpInst.addOperand(Inst.getOperand(3)); // alignment
    7940             :     TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
    7941             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7942             :                                             Spacing));
    7943             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7944             :                                             Spacing * 2));
    7945             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7946             :                                             Spacing * 3));
    7947             :     TmpInst.addOperand(Inst.getOperand(1)); // lane
    7948             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    7949             :     TmpInst.addOperand(Inst.getOperand(5));
    7950             :     Inst = TmpInst;
    7951             :     return true;
    7952             :   }
    7953             : 
    7954             :   // VLD3DUP single 3-element structure to all lanes instructions.
    7955             :   case ARM::VLD3DUPdAsm_8:
    7956          22 :   case ARM::VLD3DUPdAsm_16:
    7957             :   case ARM::VLD3DUPdAsm_32:
    7958          22 :   case ARM::VLD3DUPqAsm_8:
    7959          44 :   case ARM::VLD3DUPqAsm_16:
    7960          22 :   case ARM::VLD3DUPqAsm_32: {
    7961          44 :     MCInst TmpInst;
    7962          22 :     unsigned Spacing;
    7963          44 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7964             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7965             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7966             :                                             Spacing));
    7967          22 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7968          44 :                                             Spacing * 2));
    7969          22 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    7970          44 :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    7971          22 :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    7972          44 :     TmpInst.addOperand(Inst.getOperand(4));
    7973             :     Inst = TmpInst;
    7974             :     return true;
    7975             :   }
    7976             : 
    7977             :   case ARM::VLD3DUPdWB_fixed_Asm_8:
    7978             :   case ARM::VLD3DUPdWB_fixed_Asm_16:
    7979             :   case ARM::VLD3DUPdWB_fixed_Asm_32:
    7980             :   case ARM::VLD3DUPqWB_fixed_Asm_8:
    7981             :   case ARM::VLD3DUPqWB_fixed_Asm_16:
    7982             :   case ARM::VLD3DUPqWB_fixed_Asm_32: {
    7983             :     MCInst TmpInst;
    7984             :     unsigned Spacing;
    7985             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    7986             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    7987             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7988             :                                             Spacing));
    7989          12 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    7990             :                                             Spacing * 2));
    7991          12 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    7992          24 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    7993          12 :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    7994          24 :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    7995             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    7996             :     TmpInst.addOperand(Inst.getOperand(4));
    7997             :     Inst = TmpInst;
    7998             :     return true;
    7999             :   }
    8000             : 
    8001             :   case ARM::VLD3DUPdWB_register_Asm_8:
    8002             :   case ARM::VLD3DUPdWB_register_Asm_16:
    8003             :   case ARM::VLD3DUPdWB_register_Asm_32:
    8004             :   case ARM::VLD3DUPqWB_register_Asm_8:
    8005             :   case ARM::VLD3DUPqWB_register_Asm_16:
    8006             :   case ARM::VLD3DUPqWB_register_Asm_32: {
    8007             :     MCInst TmpInst;
    8008             :     unsigned Spacing;
    8009             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8010             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8011          12 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8012             :                                             Spacing));
    8013          12 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8014          24 :                                             Spacing * 2));
    8015          12 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8016          24 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8017             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8018             :     TmpInst.addOperand(Inst.getOperand(3)); // Rm
    8019             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8020          12 :     TmpInst.addOperand(Inst.getOperand(5));
    8021             :     Inst = TmpInst;
    8022             :     return true;
    8023             :   }
    8024             : 
    8025             :   // VLD3 multiple 3-element structure instructions.
    8026             :   case ARM::VLD3dAsm_8:
    8027             :   case ARM::VLD3dAsm_16:
    8028             :   case ARM::VLD3dAsm_32:
    8029             :   case ARM::VLD3qAsm_8:
    8030             :   case ARM::VLD3qAsm_16:
    8031             :   case ARM::VLD3qAsm_32: {
    8032             :     MCInst TmpInst;
    8033             :     unsigned Spacing;
    8034             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8035          12 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8036             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8037          12 :                                             Spacing));
    8038          24 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8039          12 :                                             Spacing * 2));
    8040          24 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8041             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8042             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8043             :     TmpInst.addOperand(Inst.getOperand(4));
    8044             :     Inst = TmpInst;
    8045             :     return true;
    8046             :   }
    8047             : 
    8048             :   case ARM::VLD3dWB_fixed_Asm_8:
    8049             :   case ARM::VLD3dWB_fixed_Asm_16:
    8050             :   case ARM::VLD3dWB_fixed_Asm_32:
    8051             :   case ARM::VLD3qWB_fixed_Asm_8:
    8052             :   case ARM::VLD3qWB_fixed_Asm_16:
    8053             :   case ARM::VLD3qWB_fixed_Asm_32: {
    8054             :     MCInst TmpInst;
    8055             :     unsigned Spacing;
    8056             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8057             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8058             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8059             :                                             Spacing));
    8060          21 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8061             :                                             Spacing * 2));
    8062          21 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8063          42 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8064          21 :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8065          42 :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    8066             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8067             :     TmpInst.addOperand(Inst.getOperand(4));
    8068             :     Inst = TmpInst;
    8069             :     return true;
    8070             :   }
    8071             : 
    8072             :   case ARM::VLD3dWB_register_Asm_8:
    8073             :   case ARM::VLD3dWB_register_Asm_16:
    8074             :   case ARM::VLD3dWB_register_Asm_32:
    8075             :   case ARM::VLD3qWB_register_Asm_8:
    8076             :   case ARM::VLD3qWB_register_Asm_16:
    8077             :   case ARM::VLD3qWB_register_Asm_32: {
    8078             :     MCInst TmpInst;
    8079             :     unsigned Spacing;
    8080             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8081             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8082          24 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8083             :                                             Spacing));
    8084          24 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8085          48 :                                             Spacing * 2));
    8086          24 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8087          48 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8088             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8089             :     TmpInst.addOperand(Inst.getOperand(3)); // Rm
    8090             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8091          24 :     TmpInst.addOperand(Inst.getOperand(5));
    8092             :     Inst = TmpInst;
    8093             :     return true;
    8094             :   }
    8095             : 
    8096             :   // VLD4DUP single 3-element structure to all lanes instructions.
    8097             :   case ARM::VLD4DUPdAsm_8:
    8098             :   case ARM::VLD4DUPdAsm_16:
    8099             :   case ARM::VLD4DUPdAsm_32:
    8100             :   case ARM::VLD4DUPqAsm_8:
    8101             :   case ARM::VLD4DUPqAsm_16:
    8102             :   case ARM::VLD4DUPqAsm_32: {
    8103             :     MCInst TmpInst;
    8104             :     unsigned Spacing;
    8105             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8106          18 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8107             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8108          18 :                                             Spacing));
    8109          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8110          18 :                                             Spacing * 2));
    8111          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8112             :                                             Spacing * 3));
    8113             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8114             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8115             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8116             :     TmpInst.addOperand(Inst.getOperand(4));
    8117             :     Inst = TmpInst;
    8118             :     return true;
    8119             :   }
    8120             : 
    8121             :   case ARM::VLD4DUPdWB_fixed_Asm_8:
    8122             :   case ARM::VLD4DUPdWB_fixed_Asm_16:
    8123             :   case ARM::VLD4DUPdWB_fixed_Asm_32:
    8124             :   case ARM::VLD4DUPqWB_fixed_Asm_8:
    8125             :   case ARM::VLD4DUPqWB_fixed_Asm_16:
    8126             :   case ARM::VLD4DUPqWB_fixed_Asm_32: {
    8127             :     MCInst TmpInst;
    8128             :     unsigned Spacing;
    8129             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8130             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8131          20 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8132             :                                             Spacing));
    8133          20 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8134          40 :                                             Spacing * 2));
    8135          20 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8136          40 :                                             Spacing * 3));
    8137          20 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8138          40 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8139             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8140             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    8141             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8142             :     TmpInst.addOperand(Inst.getOperand(4));
    8143             :     Inst = TmpInst;
    8144             :     return true;
    8145             :   }
    8146             : 
    8147             :   case ARM::VLD4DUPdWB_register_Asm_8:
    8148             :   case ARM::VLD4DUPdWB_register_Asm_16:
    8149             :   case ARM::VLD4DUPdWB_register_Asm_32:
    8150             :   case ARM::VLD4DUPqWB_register_Asm_8:
    8151             :   case ARM::VLD4DUPqWB_register_Asm_16:
    8152             :   case ARM::VLD4DUPqWB_register_Asm_32: {
    8153             :     MCInst TmpInst;
    8154             :     unsigned Spacing;
    8155          20 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8156             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8157          20 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8158          40 :                                             Spacing));
    8159          20 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8160          40 :                                             Spacing * 2));
    8161          20 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8162          40 :                                             Spacing * 3));
    8163             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8164             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8165             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8166          20 :     TmpInst.addOperand(Inst.getOperand(3)); // Rm
    8167             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8168             :     TmpInst.addOperand(Inst.getOperand(5));
    8169             :     Inst = TmpInst;
    8170             :     return true;
    8171             :   }
    8172             : 
    8173             :   // VLD4 multiple 4-element structure instructions.
    8174             :   case ARM::VLD4dAsm_8:
    8175             :   case ARM::VLD4dAsm_16:
    8176             :   case ARM::VLD4dAsm_32:
    8177             :   case ARM::VLD4qAsm_8:
    8178             :   case ARM::VLD4qAsm_16:
    8179             :   case ARM::VLD4qAsm_32: {
    8180             :     MCInst TmpInst;
    8181          20 :     unsigned Spacing;
    8182             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8183          20 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8184          40 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8185          20 :                                             Spacing));
    8186          40 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8187          20 :                                             Spacing * 2));
    8188          40 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8189             :                                             Spacing * 3));
    8190             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8191             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8192             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8193             :     TmpInst.addOperand(Inst.getOperand(4));
    8194             :     Inst = TmpInst;
    8195             :     return true;
    8196             :   }
    8197             : 
    8198             :   case ARM::VLD4dWB_fixed_Asm_8:
    8199             :   case ARM::VLD4dWB_fixed_Asm_16:
    8200             :   case ARM::VLD4dWB_fixed_Asm_32:
    8201             :   case ARM::VLD4qWB_fixed_Asm_8:
    8202             :   case ARM::VLD4qWB_fixed_Asm_16:
    8203             :   case ARM::VLD4qWB_fixed_Asm_32: {
    8204             :     MCInst TmpInst;
    8205             :     unsigned Spacing;
    8206             :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8207             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8208          33 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8209             :                                             Spacing));
    8210          33 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8211          66 :                                             Spacing * 2));
    8212          33 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8213          66 :                                             Spacing * 3));
    8214          33 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8215          66 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8216             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8217             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    8218             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8219             :     TmpInst.addOperand(Inst.getOperand(4));
    8220             :     Inst = TmpInst;
    8221             :     return true;
    8222             :   }
    8223             : 
    8224             :   case ARM::VLD4dWB_register_Asm_8:
    8225             :   case ARM::VLD4dWB_register_Asm_16:
    8226             :   case ARM::VLD4dWB_register_Asm_32:
    8227             :   case ARM::VLD4qWB_register_Asm_8:
    8228             :   case ARM::VLD4qWB_register_Asm_16:
    8229             :   case ARM::VLD4qWB_register_Asm_32: {
    8230             :     MCInst TmpInst;
    8231             :     unsigned Spacing;
    8232          36 :     TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
    8233             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8234          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8235          72 :                                             Spacing));
    8236          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8237          72 :                                             Spacing * 2));
    8238          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8239          72 :                                             Spacing * 3));
    8240             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8241             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8242             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8243          36 :     TmpInst.addOperand(Inst.getOperand(3)); // Rm
    8244             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8245             :     TmpInst.addOperand(Inst.getOperand(5));
    8246             :     Inst = TmpInst;
    8247             :     return true;
    8248             :   }
    8249             : 
    8250             :   // VST3 multiple 3-element structure instructions.
    8251             :   case ARM::VST3dAsm_8:
    8252             :   case ARM::VST3dAsm_16:
    8253             :   case ARM::VST3dAsm_32:
    8254             :   case ARM::VST3qAsm_8:
    8255             :   case ARM::VST3qAsm_16:
    8256             :   case ARM::VST3qAsm_32: {
    8257             :     MCInst TmpInst;
    8258          30 :     unsigned Spacing;
    8259             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    8260          30 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8261          60 :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8262          30 :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8263          60 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8264          30 :                                             Spacing));
    8265          60 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8266             :                                             Spacing * 2));
    8267             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8268             :     TmpInst.addOperand(Inst.getOperand(4));
    8269             :     Inst = TmpInst;
    8270             :     return true;
    8271             :   }
    8272             : 
    8273             :   case ARM::VST3dWB_fixed_Asm_8:
    8274             :   case ARM::VST3dWB_fixed_Asm_16:
    8275             :   case ARM::VST3dWB_fixed_Asm_32:
    8276             :   case ARM::VST3qWB_fixed_Asm_8:
    8277             :   case ARM::VST3qWB_fixed_Asm_16:
    8278             :   case ARM::VST3qWB_fixed_Asm_32: {
    8279             :     MCInst TmpInst;
    8280             :     unsigned Spacing;
    8281             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    8282             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8283             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8284             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8285          21 :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    8286             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8287             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8288             :                                             Spacing));
    8289          21 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8290          42 :                                             Spacing * 2));
    8291          21 :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8292          42 :     TmpInst.addOperand(Inst.getOperand(4));
    8293             :     Inst = TmpInst;
    8294             :     return true;
    8295             :   }
    8296             : 
    8297             :   case ARM::VST3dWB_register_Asm_8:
    8298             :   case ARM::VST3dWB_register_Asm_16:
    8299             :   case ARM::VST3dWB_register_Asm_32:
    8300             :   case ARM::VST3qWB_register_Asm_8:
    8301             :   case ARM::VST3qWB_register_Asm_16:
    8302             :   case ARM::VST3qWB_register_Asm_32: {
    8303             :     MCInst TmpInst;
    8304             :     unsigned Spacing;
    8305             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    8306             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8307          24 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8308             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8309             :     TmpInst.addOperand(Inst.getOperand(3)); // Rm
    8310             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8311          24 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8312             :                                             Spacing));
    8313          24 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8314          48 :                                             Spacing * 2));
    8315          24 :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8316          48 :     TmpInst.addOperand(Inst.getOperand(5));
    8317             :     Inst = TmpInst;
    8318             :     return true;
    8319             :   }
    8320             : 
    8321             :   // VST4 multiple 3-element structure instructions.
    8322             :   case ARM::VST4dAsm_8:
    8323             :   case ARM::VST4dAsm_16:
    8324             :   case ARM::VST4dAsm_32:
    8325             :   case ARM::VST4qAsm_8:
    8326             :   case ARM::VST4qAsm_16:
    8327             :   case ARM::VST4qAsm_32: {
    8328             :     MCInst TmpInst;
    8329             :     unsigned Spacing;
    8330             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    8331          18 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8332             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8333             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8334             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8335             :                                             Spacing));
    8336             :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8337          18 :                                             Spacing * 2));
    8338          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8339          18 :                                             Spacing * 3));
    8340          36 :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8341             :     TmpInst.addOperand(Inst.getOperand(4));
    8342             :     Inst = TmpInst;
    8343             :     return true;
    8344             :   }
    8345             : 
    8346             :   case ARM::VST4dWB_fixed_Asm_8:
    8347             :   case ARM::VST4dWB_fixed_Asm_16:
    8348             :   case ARM::VST4dWB_fixed_Asm_32:
    8349             :   case ARM::VST4qWB_fixed_Asm_8:
    8350             :   case ARM::VST4qWB_fixed_Asm_16:
    8351             :   case ARM::VST4qWB_fixed_Asm_32: {
    8352             :     MCInst TmpInst;
    8353             :     unsigned Spacing;
    8354             :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    8355             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8356          32 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8357             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8358             :     TmpInst.addOperand(MCOperand::createReg(0)); // Rm
    8359             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8360          32 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8361          64 :                                             Spacing));
    8362          32 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8363          64 :                                             Spacing * 2));
    8364          32 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8365          64 :                                             Spacing * 3));
    8366             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8367             :     TmpInst.addOperand(Inst.getOperand(4));
    8368             :     Inst = TmpInst;
    8369             :     return true;
    8370             :   }
    8371             : 
    8372             :   case ARM::VST4dWB_register_Asm_8:
    8373             :   case ARM::VST4dWB_register_Asm_16:
    8374             :   case ARM::VST4dWB_register_Asm_32:
    8375             :   case ARM::VST4qWB_register_Asm_8:
    8376             :   case ARM::VST4qWB_register_Asm_16:
    8377             :   case ARM::VST4qWB_register_Asm_32: {
    8378             :     MCInst TmpInst;
    8379             :     unsigned Spacing;
    8380          36 :     TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
    8381             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8382             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
    8383             :     TmpInst.addOperand(Inst.getOperand(2)); // alignment
    8384          36 :     TmpInst.addOperand(Inst.getOperand(3)); // Rm
    8385             :     TmpInst.addOperand(Inst.getOperand(0)); // Vd
    8386          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8387          72 :                                             Spacing));
    8388          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8389          72 :                                             Spacing * 2));
    8390          36 :     TmpInst.addOperand(MCOperand::createReg(Inst.getOperand(0).getReg() +
    8391          72 :                                             Spacing * 3));
    8392             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8393             :     TmpInst.addOperand(Inst.getOperand(5));
    8394             :     Inst = TmpInst;
    8395             :     return true;
    8396             :   }
    8397             : 
    8398             :   // Handle encoding choice for the shift-immediate instructions.
    8399             :   case ARM::t2LSLri:
    8400             :   case ARM::t2LSRri:
    8401             :   case ARM::t2ASRri:
    8402             :     if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
    8403             :         isARMLowRegister(Inst.getOperand(1).getReg()) &&
    8404             :         Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) &&
    8405             :         !HasWideQualifier) {
    8406          30 :       unsigned NewOpc;
    8407             :       switch (Inst.getOpcode()) {
    8408             :       default: llvm_unreachable("unexpected opcode");
    8409             :       case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
    8410             :       case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
    8411             :       case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
    8412          30 :       }
    8413          60 :       // The Thumb1 operands aren't in the same order. Awesome, eh?
    8414          30 :       MCInst TmpInst;
    8415          60 :       TmpInst.setOpcode(NewOpc);
    8416          30 :       TmpInst.addOperand(Inst.getOperand(0));
    8417          60 :       TmpInst.addOperand(Inst.getOperand(5));
    8418             :       TmpInst.addOperand(Inst.getOperand(1));
    8419             :       TmpInst.addOperand(Inst.getOperand(2));
    8420             :       TmpInst.addOperand(Inst.getOperand(3));
    8421             :       TmpInst.addOperand(Inst.getOperand(4));
    8422             :       Inst = TmpInst;
    8423             :       return true;
    8424             :     }
    8425             :     return false;
    8426             : 
    8427             :   // Handle the Thumb2 mode MOV complex aliases.
    8428          73 :   case ARM::t2MOVsr:
    8429         100 :   case ARM::t2MOVSsr: {
    8430          60 :     // Which instruction to expand to depends on the CCOut operand and
    8431             :     // whether we're in an IT block if the register operands are low
    8432             :     // registers.
    8433             :     bool isNarrow = false;
    8434           0 :     if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
    8435             :         isARMLowRegister(Inst.getOperand(1).getReg()) &&
    8436           0 :         isARMLowRegister(Inst.getOperand(2).getReg()) &&
    8437           0 :         Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
    8438             :         inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr) &&
    8439             :         !HasWideQualifier)
    8440             :       isNarrow = true;
    8441             :     MCInst TmpInst;
    8442             :     unsigned newOpc;
    8443             :     switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
    8444             :     default: llvm_unreachable("unexpected opcode!");
    8445             :     case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
    8446             :     case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
    8447             :     case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
    8448             :     case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
    8449             :     }
    8450             :     TmpInst.setOpcode(newOpc);
    8451             :     TmpInst.addOperand(Inst.getOperand(0)); // Rd
    8452             :     if (isNarrow)
    8453             :       TmpInst.addOperand(MCOperand::createReg(
    8454          30 :           Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
    8455             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8456             :     TmpInst.addOperand(Inst.getOperand(2)); // Rm
    8457             :     TmpInst.addOperand(Inst.getOperand(4)); // CondCode
    8458             :     TmpInst.addOperand(Inst.getOperand(5));
    8459             :     if (!isNarrow)
    8460          30 :       TmpInst.addOperand(MCOperand::createReg(
    8461          30 :           Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
    8462          30 :     Inst = TmpInst;
    8463          26 :     return true;
    8464          26 :   }
    8465             :   case ARM::t2MOVsi:
    8466             :   case ARM::t2MOVSsi: {
    8467             :     // Which instruction to expand to depends on the CCOut operand and
    8468             :     // whether we're in an IT block if the register operands are low
    8469          30 :     // registers.
    8470           0 :     bool isNarrow = false;
    8471           6 :     if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
    8472           8 :         isARMLowRegister(Inst.getOperand(1).getReg()) &&
    8473           8 :         inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi) &&
    8474           8 :         !HasWideQualifier)
    8475             :       isNarrow = true;
    8476             :     MCInst TmpInst;
    8477             :     unsigned newOpc;
    8478          30 :     unsigned Shift = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
    8479          16 :     unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
    8480          24 :     bool isMov = false;
    8481             :     // MOV rd, rm, LSL #0 is actually a MOV instruction
    8482             :     if (Shift == ARM_AM::lsl && Amount == 0) {
    8483             :       isMov = true;
    8484             :       // The 16-bit encoding of MOV rd, rm, LSL #N is explicitly encoding T2 of
    8485          30 :       // MOV (register) in the ARMv8-A and ARMv8-M manuals, and immediate 0 is
    8486          14 :       // unpredictable in an IT block so the 32-bit encoding T3 has to be used
    8487          16 :       // instead.
    8488             :       if (inITBlock()) {
    8489             :         isNarrow = false;
    8490             :       }
    8491          30 :       newOpc = isNarrow ? ARM::tMOVSr : ARM::t2MOVr;
    8492             :     } else {
    8493             :       switch(Shift) {
    8494             :       default: llvm_unreachable("unexpected opcode!");
    8495             :       case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
    8496             :       case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
    8497          30 :       case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
    8498          27 :       case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
    8499          26 :       case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
    8500             :       }
    8501             :     }
    8502             :     if (Amount == 32) Amount = 0;
    8503             :     TmpInst.setOpcode(newOpc);
    8504          30 :     TmpInst.addOperand(Inst.getOperand(0)); // Rd
    8505             :     if (isNarrow && !isMov)
    8506             :       TmpInst.addOperand(MCOperand::createReg(
    8507             :           Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
    8508          30 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8509             :     if (newOpc != ARM::t2RRX && !isMov)
    8510             :       TmpInst.addOperand(MCOperand::createImm(Amount));
    8511             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8512             :     TmpInst.addOperand(Inst.getOperand(4));
    8513             :     if (!isNarrow)
    8514          12 :       TmpInst.addOperand(MCOperand::createReg(
    8515             :           Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
    8516             :     Inst = TmpInst;
    8517           4 :     return true;
    8518             :   }
    8519             :   // Handle the ARM mode MOV complex aliases.
    8520           0 :   case ARM::ASRr:
    8521           4 :   case ARM::LSRr:
    8522           4 :   case ARM::LSLr:
    8523           4 :   case ARM::RORr: {
    8524             :     ARM_AM::ShiftOpc ShiftTy;
    8525           2 :     switch(Inst.getOpcode()) {
    8526             :     default: llvm_unreachable("unexpected opcode!");
    8527             :     case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
    8528          30 :     case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
    8529             :     case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
    8530             :     case ARM::RORr: ShiftTy = ARM_AM::ror; break;
    8531          30 :     }
    8532           2 :     unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
    8533           2 :     MCInst TmpInst;
    8534             :     TmpInst.setOpcode(ARM::MOVsr);
    8535          30 :     TmpInst.addOperand(Inst.getOperand(0)); // Rd
    8536          16 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8537             :     TmpInst.addOperand(Inst.getOperand(2)); // Rm
    8538             :     TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
    8539          30 :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8540          28 :     TmpInst.addOperand(Inst.getOperand(4));
    8541          43 :     TmpInst.addOperand(Inst.getOperand(5)); // cc_out
    8542             :     Inst = TmpInst;
    8543             :     return true;
    8544             :   }
    8545             :   case ARM::ASRi:
    8546           0 :   case ARM::LSRi:
    8547             :   case ARM::LSLi:
    8548             :   case ARM::RORi: {
    8549             :     ARM_AM::ShiftOpc ShiftTy;
    8550             :     switch(Inst.getOpcode()) {
    8551             :     default: llvm_unreachable("unexpected opcode!");
    8552           0 :     case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
    8553             :     case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
    8554           0 :     case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
    8555           0 :     case ARM::RORi: ShiftTy = ARM_AM::ror; break;
    8556           0 :     }
    8557             :     // A shift by zero is a plain MOVr, not a MOVsi.
    8558             :     unsigned Amt = Inst.getOperand(2).getImm();
    8559             :     unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
    8560             :     // A shift by 32 should be encoded as 0 when permitted
    8561             :     if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
    8562             :       Amt = 0;
    8563             :     unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
    8564           0 :     MCInst TmpInst;
    8565             :     TmpInst.setOpcode(Opc);
    8566             :     TmpInst.addOperand(Inst.getOperand(0)); // Rd
    8567             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8568             :     if (Opc == ARM::MOVsi)
    8569             :       TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
    8570             :     TmpInst.addOperand(Inst.getOperand(3)); // CondCode
    8571          57 :     TmpInst.addOperand(Inst.getOperand(4));
    8572             :     TmpInst.addOperand(Inst.getOperand(5)); // cc_out
    8573             :     Inst = TmpInst;
    8574             :     return true;
    8575             :   }
    8576             :   case ARM::RRXi: {
    8577           0 :     unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
    8578             :     MCInst TmpInst;
    8579          10 :     TmpInst.setOpcode(ARM::MOVsi);
    8580          26 :     TmpInst.addOperand(Inst.getOperand(0)); // Rd
    8581          11 :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8582             :     TmpInst.addOperand(MCOperand::createImm(Shifter)); // Shift value and ty
    8583             :     TmpInst.addOperand(Inst.getOperand(2)); // CondCode
    8584          57 :     TmpInst.addOperand(Inst.getOperand(3));
    8585          57 :     TmpInst.addOperand(Inst.getOperand(4)); // cc_out
    8586             :     Inst = TmpInst;
    8587          57 :     return true;
    8588             :   }
    8589             :   case ARM::t2LDMIA_UPD: {
    8590             :     // If this is a load of a single register, then we should use
    8591             :     // a post-indexed LDR instruction instead, per the ARM ARM.
    8592             :     if (Inst.getNumOperands() != 5)
    8593             :       return false;
    8594          57 :     MCInst TmpInst;
    8595          25 :     TmpInst.setOpcode(ARM::t2LDR_POST);
    8596             :     TmpInst.addOperand(Inst.getOperand(4)); // Rt
    8597             :     TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
    8598             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8599             :     TmpInst.addOperand(MCOperand::createImm(4));
    8600             :     TmpInst.addOperand(Inst.getOperand(2)); // CondCode
    8601             :     TmpInst.addOperand(Inst.getOperand(3));
    8602             :     Inst = TmpInst;
    8603             :     return true;
    8604             :   }
    8605             :   case ARM::t2STMDB_UPD: {
    8606             :     // If this is a store of a single register, then we should use
    8607             :     // a pre-indexed STR instruction instead, per the ARM ARM.
    8608          16 :     if (Inst.getNumOperands() != 5)
    8609             :       return false;
    8610             :     MCInst TmpInst;
    8611             :     TmpInst.setOpcode(ARM::t2STR_PRE);
    8612             :     TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
    8613             :     TmpInst.addOperand(Inst.getOperand(4)); // Rt
    8614             :     TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8615             :     TmpInst.addOperand(MCOperand::createImm(-4));
    8616             :     TmpInst.addOperand(Inst.getOperand(2)); // CondCode
    8617             :     TmpInst.addOperand(Inst.getOperand(3));
    8618          45 :     Inst = TmpInst;
    8619             :     return true;
    8620             :   }
    8621             :   case ARM::LDMIA_UPD:
    8622             :     // If this is a load of a single register via a 'pop', then we should use
    8623             :     // a post-indexed LDR instruction instead, per the ARM ARM.
    8624             :     if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "pop" &&
    8625           9 :         Inst.getNumOperands() == 5) {
    8626             :       MCInst TmpInst;
    8627             :       TmpInst.setOpcode(ARM::LDR_POST_IMM);
    8628             :       TmpInst.addOperand(Inst.getOperand(4)); // Rt
    8629             :       TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
    8630             :       TmpInst.addOperand(Inst.getOperand(1)); // Rn
    8631             :       TmpInst.addOperand(MCOperand::createReg(0));  // am2offset
    8632             :       TmpInst.addOperand(MCOperand::createImm(4));
    8633             :       TmpInst.addOperand(Inst.getOperand(2)); // CondCode
    8634          14 :       TmpInst.addOperand(Inst.getOperand(3));
    8635             :       Inst = TmpInst;
    8636             :       return true;
    8637             :     }
    8638             :     break;
    8639             :   case ARM::STMDB_UPD:
    8640             :     // If this is a store of a single register via a 'push', then we should use
    8641           4 :     // a pre-indexed STR instruction instead, per the ARM ARM.
    8642             :     if (static_cast<ARMOperand &>(*Operands[0]).getToken() == "push" &&
    8643             :         Inst.getNumOperands() == 5) {
    8644             :       MCInst TmpInst;
    8645             :       TmpInst.setOpcode(ARM::STR_PRE_IMM);
    8646             :       TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
    8647             :       TmpInst.addOperand(Inst.getOperand(4)); // Rt
    8648             :       TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
    8649             :       TmpInst.addOperand(MCOperand::createImm(-4));
    8650         119 :       TmpInst.addOperand(Inst.getOperand(2)); // CondCode
    8651             :       TmpInst.addOperand(Inst.getOperand(3));
    8652             :       Inst = TmpInst;
    8653             :     }
    8654             :     break;
    8655             :   case ARM::t2ADDri12:
    8656             :     // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
    8657          12 :     // mnemonic was used (not "addw"), encoding T3 is preferred.
    8658          12 :     if (static_cast<ARMOperand &>(*Operands[0]).getToken() != "add" ||
    8659             :         ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
    8660             :       break;
    8661             :     Inst.setOpcode(ARM::t2ADDri);
    8662             :     Inst.addOperand(MCOperand::createReg(0)); // cc_out
    8663             :     break;
    8664             :   case ARM::t2SUBri12:
    8665             :     // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
    8666             :     // mnemonic was used (not "subw"), encoding T3 is preferred.
    8667             :     if (static_cast<ARMOperand &>(*Operands[0]).getToken() != "sub" ||
    8668         131 :         ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
    8669             :       break;
    8670             :     Inst.setOpcode(ARM::t2SUBri);
    8671             :     Inst.addOperand(MCOperand::createReg(0)); // cc_out
    8672             :     break;
    8673             :   case ARM::tADDi8:
    8674             :     // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
    8675          15 :     // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
    8676             :     // to encoding T2 if <Rd> is specified and encoding T2 is preferred
    8677             :     // to encoding T1 if <Rd> is omitted."
    8678             :     if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
    8679             :       Inst.setOpcode(ARM::tADDi3);
    8680             :       return true;
    8681             :     }
    8682             :     break;
    8683             :   case ARM::tSUBi8:
    8684          58 :     // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
    8685          16 :     // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
    8686             :     // to encoding T2 if <Rd> is specified and encoding T2 is preferred
    8687             :     // to encoding T1 if <Rd> is omitted."
    8688           8 :     if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
    8689           8 :       Inst.setOpcode(ARM::tSUBi3);
    8690             :       return true;
    8691             :     }
    8692             :     break;
    8693          57 :   case ARM::t2ADDri:
    8694           6 :   case ARM::t2SUBri: {
    8695             :     // If the destination and first source operand are the same, and
    8696             :     // the flags are compatible with the current IT status, use encoding T2
    8697           0 :     // instead of T3. For compatibility with the system 'as'. Make sure the
    8698           0 :     // wide encoding wasn't explicit.
    8699             :     if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
    8700             :         !isARMLowRegister(Inst.getOperand(0).getReg()) ||
    8701             :         (Inst.getOperand(2).isImm() &&
    8702             :          (unsigned)Inst.getOperand(2).getImm() > 255) ||
    8703             :         Inst.getOperand(5).getReg() != (inITBlock() ? 0 : ARM::CPSR) ||
    8704          62 :         HasWideQualifier)
    8705             :       break;
    8706           0 :     MCInst TmpInst;
    8707             :     TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
    8708             :                       ARM::tADDi8 : ARM::tSUBi8);
    8709             :     TmpInst.addOperand(Inst.getOperand(0));
    8710             :     TmpInst.addOperand(Inst.getOperand(5));
    8711             :     TmpInst.addOperand(Inst.getOperand(0));
    8712             :     TmpInst.addOperand(Inst.getOperand(2));
    8713             :     TmpInst.addOperand(Inst.getOperand(3));
    8714          16 :     TmpInst.addOperand(Inst.getOperand(4));
    8715             :     Inst = TmpInst;
    8716           0 :     return true;
    8717             :   }
    8718             :   case ARM::t2ADDrr: {
    8719             :     // If the destination and first source operand are the same, and
    8720             :     // there's no setting of the flags, use encoding T2 instead of T3.
    8721             :     // Note that this is only for ADD, not SUB. This mirrors the system
    8722             :     // 'as' behaviour.  Also take advantage of ADD being commutative.
    8723             :     // Make sure the wide encoding wasn't explicit.
    8724             :     bool Swap = false;
    8725         195 :     auto DestReg = Inst.getOperand(0).getReg();
    8726          40 :     bool Transform = DestReg == Inst.getOperand(1).getReg();
    8727          40 :     if (!Transform && DestReg == Inst.getOperand(2).getReg()) {
    8728          72 :       Transform = true;
    8729         245 :       Swap = true;
    8730             :     }
    8731             :     if (!Transform ||
    8732             :         Inst.getOperand(5).getReg() != 0 ||
    8733           8 :         HasWideQualifier)
    8734             :       break;
    8735             :     MCInst TmpInst;
    8736             :     TmpInst.setOpcode(ARM::tADDhirr);
    8737             :     TmpInst.addOperand(Inst.getOperand(0));
    8738             :     TmpInst.addOperand(Inst.getOperand(0));
    8739             :     TmpInst.addOperand(Inst.getOperand(Swap ? 1 : 2));
    8740             :     TmpInst.addOperand(Inst.getOperand(3));
    8741             :     TmpInst.addOperand(Inst.getOperand(4));
    8742             :     Inst = TmpInst;
    8743             :     return true;
    8744          72 :   }
    8745             :   case ARM::tADDrSP:
    8746             :     // If the non-SP source operand and the destination operand are not the
    8747             :     // same, we need to use the 32-bit encoding if it's available.
    8748             :     if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
    8749             :       Inst.setOpcode(ARM::t2ADDrr);
    8750             :       Inst.addOperand(MCOperand::createReg(0)); // cc_out
    8751          72 :       return true;
    8752          72 :     }
    8753          72 :     break;
    8754             :   case ARM::tB:
    8755             :     // A Thumb conditional branch outside of an IT block is a tBcc.
    8756             :     if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
    8757          53 :       Inst.setOpcode(ARM::tBcc);
    8758          72 :       return true;
    8759             :     }
    8760             :     break;
    8761             :   case ARM::t2B:
    8762             :     // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
    8763             :     if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
    8764             :       Inst.setOpcode(ARM::t2Bcc);
    8765          12 :       return true;
    8766             :     }
    8767             :     break;
    8768             :   case ARM::t2Bcc:
    8769             :     // If the conditional is AL or we're in an IT block, we really want t2B.
    8770             :     if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
    8771             :       Inst.setOpcode(ARM::t2B);
    8772             :       return true;
    8773             :     }
    8774          16 :     break;
    8775             :   case ARM::tBcc:
    8776           6 :     // If the conditional is AL, we really want tB.
    8777           6 :     if (Inst.getOperand(1).getImm() == ARMCC::AL) {
    8778             :       Inst.setOpcode(ARM::tB);
    8779             :       return true;
    8780             :     }
    8781             :     break;
    8782          94 :   case ARM::tLDMIA: {
    8783             :     // If the register list contains any high registers, or if the writeback
    8784           0 :     // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
    8785             :     // instead if we're in Thumb2. Otherwise, this should have generated
    8786             :     // an error in validateInstruction().
    8787             :     unsigned Rn = Inst.getOperand(0).getReg();
    8788             :     bool hasWritebackToken =
    8789          93 :         (static_cast<ARMOperand &>(*Operands[3]).isToken() &&
    8790             :          static_cast<ARMOperand &>(*Operands[3]).getToken() == "!");
    8791           0 :     bool listContainsBase;
    8792             :     if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
    8793             :         (!listContainsBase && !hasWritebackToken) ||
    8794             :         (listContainsBase && hasWritebackToken)) {
    8795             :       // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
    8796          65 :       assert(isThumbTwo());
    8797             :       Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
    8798           0 :       // If we're switching to the updating version, we need to insert
    8799             :       // the writeback tied operand.
    8800             :       if (hasWritebackToken)
    8801             :         Inst.insert(Inst.begin(),
    8802             :                     MCOperand::createReg(Inst.getOperand(0).getReg()));
    8803          92 :       return true;
    8804             :     }
    8805           0 :     break;
    8806             :   }
    8807             :   case ARM::tSTMIA_UPD: {
    8808             :     // If the register list contains any high registers, we need to use
    8809             :     // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
    8810             :     // should have generated an error in validateInstruction().
    8811             :     unsigned Rn = Inst.getOperand(0).getReg();
    8812             :     bool listContainsBase;
    8813          37 :     if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
    8814             :       // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
    8815          37 :       assert(isThumbTwo());
    8816          19 :       Inst.setOpcode(ARM::t2STMIA_UPD);
    8817             :       return true;
    8818          17 :     }
    8819          17 :     break;
    8820           6 :   }
    8821             :   case ARM::tPOP: {
    8822             :     bool listContainsBase;
    8823          27 :     // If the register list contains any high registers, we need to use
    8824             :     // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
    8825             :     // should have generated an error in validateInstruction().
    8826          27 :     if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
    8827             :       return false;
    8828          30 :     assert(isThumbTwo());
    8829             :     Inst.setOpcode(ARM::t2LDMIA_UPD);
    8830             :     // Add the base register and writeback operands.
    8831             :     Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
    8832             :     Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
    8833             :     return true;
    8834             :   }
    8835             :   case ARM::tPUSH: {
    8836             :     bool listContainsBase;
    8837             :     if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
    8838             :       return false;
    8839             :     assert(isThumbTwo());
    8840             :     Inst.setOpcode(ARM::t2STMDB_UPD);
    8841             :     // Add the base register and writeback operands.
    8842             :     Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
    8843             :     Inst.insert(Inst.begin(), MCOperand::createReg(ARM::SP));
    8844             :     return true;
    8845             :   }
    8846             :   case ARM::t2MOVi:
    8847             :     // If we can use the 16-bit encoding and the user didn't explicitly
    8848             :     // request the 32-bit variant, transform it here.
    8849             :     if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
    8850             :         (Inst.getOperand(1).isImm() &&
    8851             :          (unsigned)Inst.getOperand(1).getImm() <= 255) &&
    8852          38 :         Inst.getOperand(4).getReg() == (inITBlock() ? 0 : ARM::CPSR) &&
    8853             :         !HasWideQualifier) {
    8854             :       // The operands aren't in the same order for tMOVi8...
    8855             :       MCInst TmpInst;
    8856             :       TmpInst.setOpcode(ARM::tMOVi8);
    8857          16 :       TmpInst.addOperand(Inst.getOperand(0));
    8858          16 :       TmpInst.addOperand(Inst.getOperand(4));
    8859          16 :       TmpInst.addOperand(Inst.getOperand(1));
    8860             :       TmpInst.addOperand(Inst.getOperand(2));
    8861             :       TmpInst.addOperand(Inst.getOperand(3));
    8862             :       Inst = TmpInst;
    8863          32 :       return true;
    8864             :     }
    8865             :     break;
    8866             : 
    8867             :   case ARM::t2MOVr:
    8868           5 :     // If we can use the 16-bit encoding and the user didn't explicitly
    8869           5 :     // request the 32-bit variant, transform it here.
    8870           5 :     if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
    8871             :         isARMLowRegister(Inst.getOperand(1).getReg()) &&
    8872             :         Inst.getOperand(2).getImm() == ARMCC::AL &&
    8873             :         Inst.getOperand(4).getReg() == ARM::CPSR &&
    8874             :         !HasWideQualifier) {
    8875         114 :       // The operands aren't the same for tMOV[S]r... (no cc_out)
    8876         111 :       MCInst TmpInst;
    8877         198 :       TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
    8878         119 :       TmpInst.addOperand(Inst.getOperand(0));
    8879             :       TmpInst.addOperand(Inst.getOperand(1));
    8880             :       TmpInst.addOperand(Inst.getOperand(2));
    8881             :       TmpInst.addOperand(Inst.getOperand(3));
    8882             :       Inst = TmpInst;
    8883             :       return true;
    8884             :     }
    8885             :     break;
    8886             : 
    8887             :   case ARM::t2SXTH:
    8888             :   case ARM::t2SXTB:
    8889             :   case ARM::t2UXTH:
    8890             :   case ARM::t2UXTB:
    8891             :     // If we can use the 16-bit encoding and the user didn't explicitly
    8892             :     // request the 32-bit variant, transform it here.
    8893             :     if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
    8894             :         isARMLowRegister(Inst.getOperand(1).getReg()) &&
    8895             :         Inst.getOperand(2).getImm() == 0 &&
    8896          52 :         !HasWideQualifier) {
    8897          37 :       unsigned NewOpc;
    8898          29 :       switch (Inst.getOpcode()) {
    8899          11 :       default: llvm_unreachable("Illegal opcode!");
    8900             :       case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
    8901             :       case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
    8902             :       case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
    8903           9 :       case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
    8904             :       }
    8905             :       // The operands aren't the same for thumb1 (no rotate operand).
    8906             :       MCInst TmpInst;
    8907             :       TmpInst.setOpcode(NewOpc);
    8908             :       TmpInst.addOperand(Inst.getOperand(0));
    8909             :       TmpInst.addOperand(Inst.getOperand(1));
    8910             :       TmpInst.addOperand(Inst.getOperand(3));
    8911             :       TmpInst.addOperand(Inst.getOperand(4));
    8912             :       Inst = TmpInst;
    8913             :       return true;
    8914             :     }
    8915             :     break;
    8916             : 
    8917             :   case ARM::MOVsi: {
    8918             :     ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
    8919          66 :     // rrx shifts and asr/lsr of #32 is encoded as 0
    8920          52 :     if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
    8921          24 :       return false;
    8922             :     if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
    8923             :       // Shifting by zero is accepted as a vanilla 'MOVr'
    8924             :       MCInst TmpInst;
    8925           0 :       TmpInst.setOpcode(ARM::MOVr);
    8926             :       TmpInst.addOperand(Inst.getOperand(0));
    8927           4 :       TmpInst.addOperand(Inst.getOperand(1));
    8928           2 :       TmpInst.addOperand(Inst.getOperand(3));
    8929           2 :       TmpInst.addOperand(Inst.getOperand(4));
    8930             :       TmpInst.addOperand(Inst.getOperand(5));
    8931             :       Inst = TmpInst;
    8932             :       return true;
    8933             :     }
    8934             :     return false;
    8935             :   }
    8936             :   case ARM::ANDrsi:
    8937             :   case ARM::ORRrsi:
    8938             :   case ARM::EORrsi:
    8939             :   case ARM::BICrsi:
    8940             :   case ARM::SUBrsi:
    8941             :   case ARM::ADDrsi: {
    8942             :     unsigned newOpc;
    8943             :     ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
    8944          65 :     if (SOpc == ARM_AM::rrx) return false;
    8945             :     switch (Inst.getOpcode()) {
    8946          65 :     default: llvm_unreachable("unexpected opcode!");
    8947             :     case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
    8948          35 :     case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
    8949             :     case ARM::EORrsi: newOpc = ARM::EORrr; break;
    8950             :     case ARM::BICrsi: newOpc = ARM::BICrr; break;
    8951             :     case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
    8952             :     case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
    8953             :     }
    8954             :     // If the shift is by zero, use the non-shifted instruction definition.
    8955             :     // The exception is for right shifts, where 0 == 32
    8956             :     if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
    8957             :         !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
    8958             :       MCInst TmpInst;
    8959             :       TmpInst.setOpcode(newOpc);
    8960             :       TmpInst.addOperand(Inst.getOperand(0));
    8961             :       TmpInst.addOperand(Inst.getOperand(1));
    8962             :       TmpInst.addOperand(Inst.getOperand(2));
    8963             :       TmpInst.addOperand(Inst.getOperand(4));
    8964             :       TmpInst.addOperand(Inst.getOperand(5));
    8965             :       TmpInst.addOperand(Inst.getOperand(6));
    8966             :       Inst = TmpInst;
    8967             :       return true;
    8968             :     }
    8969         179 :     return false;
    8970         179 :   }
    8971             :   case ARM::ITasm:
    8972           0 :   case ARM::t2IT: {
    8973             :     MCOperand &MO = Inst.getOperand(1);
    8974          27 :     unsigned Mask = MO.getImm();
    8975          25 :     ARMCC::CondCodes Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
    8976          27 : 
    8977          25 :     // Set up the IT block state according to the IT instruction we just
    8978          26 :     // matched.
    8979             :     assert(!inITBlock() && "nested IT blocks?!");
    8980             :     startExplicitITBlock(Cond, Mask);
    8981             :     MO.setImm(getITMaskEncoding());
    8982         155 :     break;
    8983          30 :   }
    8984             :   case ARM::t2LSLrr:
    8985             :   case ARM::t2LSRrr:
    8986             :   case ARM::t2ASRrr:
    8987             :   case ARM::t2SBCrr:
    8988             :   case ARM::t2RORrr:
    8989             :   case ARM::t2BICrr:
    8990             :     // Assemblers should use the narrow encodings of these instructions when permissible.
    8991             :     if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
    8992             :          isARMLowRegister(Inst.getOperand(2).getReg())) &&
    8993             :         Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
    8994             :         Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) &&
    8995             :         !HasWideQualifier) {
    8996             :       unsigned NewOpc;
    8997             :       switch (Inst.getOpcode()) {
    8998             :         default: llvm_unreachable("unexpected opcode");
    8999             :         case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
    9000        2769 :         case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
    9001        2769 :         case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
    9002             :         case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
    9003             :         case ARM::t2RORrr: NewOpc = ARM::tROR; break;
    9004             :         case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
    9005             :       }
    9006             :       MCInst TmpInst;
    9007        2769 :       TmpInst.setOpcode(NewOpc);
    9008             :       TmpInst.addOperand(Inst.getOperand(0));
    9009             :       TmpInst.addOperand(Inst.getOperand(5));
    9010             :       TmpInst.addOperand(Inst.getOperand(1));
    9011             :       TmpInst.addOperand(Inst.getOperand(2));
    9012             :       TmpInst.addOperand(Inst.getOperand(3));
    9013             :       TmpInst.addOperand(Inst.getOperand(4));
    9014             :       Inst = TmpInst;
    9015             :       return true;
    9016             :     }
    9017         251 :     return false;
    9018         200 : 
    9019         229 :   case ARM::t2ANDrr:
    9020         120 :   case ARM::t2EORrr:
    9021             :   case ARM::t2ADCrr:
    9022             :   case ARM::t2ORRrr:
    9023             :     // Assemblers should use the narrow encodings of these instructions when permissible.
    9024           0 :     // These instructions are special in that they are commutable, so shorter encodings
    9025             :     // are available more often.
    9026           5 :     if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
    9027           5 :          isARMLowRegister(Inst.getOperand(2).getReg())) &&
    9028           5 :         (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
    9029           5 :          Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
    9030           5 :         Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) &&
    9031             :         !HasWideQualifier) {
    9032             :       unsigned NewOpc;
    9033             :       switch (Inst.getOpcode()) {
    9034             :         default: llvm_unreachable("unexpected opcode");
    9035             :         case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
    9036             :         case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
    9037             :         case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
    9038             :         case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
    9039             :       }
    9040             :       MCInst TmpInst;
    9041             :       TmpInst.setOpcode(NewOpc);
    9042             :       TmpInst.addOperand(Inst.getOperand(0));
    9043             :       TmpInst.addOperand(Inst.getOperand(5));
    9044             :       if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
    9045             :         TmpInst.addOperand(Inst.getOperand(1));
    9046             :         TmpInst.addOperand(Inst.getOperand(2));
    9047             :       } else {
    9048             :         TmpInst.addOperand(Inst.getOperand(2));
    9049             :         TmpInst.addOperand(Inst.getOperand(1));
    9050             :       }
    9051             :       TmpInst.addOperand(Inst.getOperand(3));
    9052         238 :       TmpInst.addOperand(Inst.getOperand(4));
    9053         170 :       Inst = TmpInst;
    9054         151 :       return true;
    9055         131 :     }
    9056         219 :     return false;
    9057             :   }
    9058             :   return false;
    9059             : }
    9060           0 : 
    9061             : unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
    9062          10 :   // 16-bit thumb arithmetic instructions either require or preclude the 'S'
    9063          10 :   // suffix depending on whether they're in an IT block or not.
    9064          10 :   unsigned Opc = Inst.getOpcode();
    9065             :   const MCInstrDesc &MCID = MII.get(Opc);
    9066             :   if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
    9067             :     assert(MCID.hasOptionalDef() &&
    9068             :            "optionally flag setting instruction missing optional def operand");
    9069             :     assert(MCID.NumOperands == Inst.getNumOperands() &&
    9070          40 :            "operand count mismatch!");
    9071             :     // Find the optional-def operand (cc_out).
    9072             :     unsigned OpNo;
    9073             :     for (OpNo = 0;
    9074             :          !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
    9075             :          ++OpNo)
    9076             :       ;
    9077             :     // If we're parsing Thumb1, reject it completely.
    9078             :     if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
    9079             :       return Match_RequiresFlagSetting;
    9080             :     // If we're parsing Thumb2, which form is legal depends on whether we're
    9081             :     // in an IT block.
    9082             :     if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
    9083             :         !inITBlock())
    9084             :       return Match_RequiresITBlock;
    9085             :     if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
    9086             :         inITBlock())
    9087       31027 :       return Match_RequiresNotITBlock;
    9088             :     // LSL with zero immediate is not allowed in an IT block
    9089             :     if (Opc == ARM::tLSLri && Inst.getOperand(3).getImm() == 0 && inITBlock())
    9090       31027 :       return Match_RequiresNotITBlock;
    9091       31027 :   } else if (isThumbOne()) {
    9092       31027 :     // Some high-register supporting Thumb1 encodings only allow both registers
    9093             :     // to be from r0-r7 when in Thumb2.
    9094             :     if (Opc == ARM::tADDhirr && !hasV6MOps() &&
    9095             :         isARMLowRegister(Inst.getOperand(1).getReg()) &&
    9096             :         isARMLowRegister(Inst.getOperand(2).getReg()))
    9097             :       return Match_RequiresThumb2;
    9098             :     // Others only require ARMv6 or later.
    9099         952 :     else if (Opc == ARM::tMOVr && !hasV6Ops() &&
    9100        1904 :              isARMLowRegister(Inst.getOperand(0).getReg()) &&
    9101             :              isARMLowRegister(Inst.getOperand(1).getReg()))
    9102             :       return Match_RequiresV6;
    9103             :   }
    9104         952 : 
    9105             :   // Before ARMv8 the rules for when SP is allowed in t2MOVr are more complex
    9106             :   // than the loop below can handle, so it uses the GPRnopc register class and
    9107             :   // we do SP handling here.
    9108         950 :   if (Opc == ARM::t2MOVr && !hasV8Ops())
    9109         239 :   {
    9110             :     // SP as both source and destination is not allowed
    9111         864 :     if (Inst.getOperand(0).getReg() == ARM::SP &&
    9112         273 :         Inst.getOperand(1).getReg() == ARM::SP)
    9113             :       return Match_RequiresV8;
    9114             :     // When flags-setting SP as either source or destination is not allowed
    9115         842 :     if (Inst.getOperand(4).getReg() == ARM::CPSR &&
    9116             :         (Inst.getOperand(0).getReg() == ARM::SP ||
    9117       30075 :          Inst.getOperand(1).getReg() == ARM::SP))
    9118             :       return Match_RequiresV8;
    9119             :   }
    9120          10 : 
    9121         927 :   // Use of SP for VMRS/VMSR is only allowed in ARM mode with the exception of
    9122           3 :   // ARMv8-A.
    9123             :   if ((Inst.getOpcode() == ARM::VMRS || Inst.getOpcode() == ARM::VMSR) &&
    9124             :       Inst.getOperand(0).getReg() == ARM::SP && (isThumb() && !hasV8Ops()))
    9125          39 :     return Match_InvalidOperand;
    9126         956 : 
    9127           2 :   for (unsigned I = 0; I < MCID.NumOperands; ++I)
    9128             :     if (MCID.OpInfo[I].RegClass == ARM::rGPRRegClassID) {
    9129             :       // rGPRRegClass excludes PC, and also excluded SP before ARMv8
    9130             :       if ((Inst.getOperand(I).getReg() == ARM::SP) && !hasV8Ops())
    9131             :         return Match_RequiresV8;
    9132             :       else if (Inst.getOperand(I).getReg() == ARM::PC)
    9133             :         return Match_InvalidOperand;
    9134       30972 :     }
    9135             : 
    9136             :   return Match_Success;
    9137          45 : }
    9138          14 : 
    9139             : namespace llvm {
    9140             : 
    9141          38 : template <> inline bool IsCPSRDead<MCInst>(const MCInst *Instr) {
    9142          17 :   return true; // In an assembly source, no need to second-guess
    9143          17 : }
    9144             : 
    9145             : } // end namespace llvm
    9146             : 
    9147             : // Returns true if Inst is unpredictable if it is in and IT block, but is not
    9148             : // the last instruction in the block.
    9149       30876 : bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const {
    9150       30940 :   const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
    9151             : 
    9152             :   // All branch & call instructions terminate IT blocks with the exception of
    9153      162883 :   // SVC.
    9154      132013 :   if (MCID.isTerminator() || (MCID.isCall() && Inst.getOpcode() != ARM::tSVC) ||
    9155             :       MCID.isReturn() || MCID.isBranch() || MCID.isIndirectBranch())
    9156       12097 :     return true;
    9157             : 
    9158       12076 :   // Any arithmetic instruction which writes to the PC also terminates the IT
    9159             :   // block.
    9160             :   for (unsigned OpIdx = 0; OpIdx < MCID.getNumDefs(); ++OpIdx) {
    9161             :     MCOperand &Op = Inst.getOperand(OpIdx);
    9162             :     if (Op.isReg() && Op.getReg() == ARM::PC)
    9163             :       return true;
    9164             :   }
    9165             : 
    9166             :   if (MCID.hasImplicitDefOfPhysReg(ARM::PC, MRI))
    9167           0 :     return true;
    9168           0 : 
    9169             :   // Instructions with variable operand lists, which write to the variable
    9170             :   // operands. We only care about Thumb instructions here, as ARM instructions
    9171             :   // obviously can't be in an IT block.
    9172             :   switch (Inst.getOpcode()) {
    9173             :   case ARM::tLDMIA:
    9174             :   case ARM::t2LDMIA:
    9175           0 :   case ARM::t2LDMIA_UPD:
    9176           0 :   case ARM::t2LDMDB:
    9177             :   case ARM::t2LDMDB_UPD:
    9178             :     if (listContainsReg(Inst, 3, ARM::PC))
    9179             :       return true;
    9180           0 :     break;
    9181           0 :   case ARM::tPOP:
    9182           0 :     if (listContainsReg(Inst, 2, ARM::PC))
    9183             :       return true;
    9184             :     break;
    9185             :   }
    9186           0 : 
    9187             :   return false;
    9188           0 : }
    9189           0 : 
    9190             : unsigned ARMAsmParser::MatchInstruction(OperandVector &Operands, MCInst &Inst,
    9191             :                                           SmallVectorImpl<NearMissInfo> &NearMisses,
    9192           0 :                                           bool MatchingInlineAsm,
    9193           0 :                                           bool &EmitInITBlock,
    9194             :                                           MCStreamer &Out) {
    9195             :   // If we can't use an implicit IT block here, just match as normal.
    9196             :   if (inExplicitITBlock() || !isThumbTwo() || !useImplicitITThumb())
    9197             :     return MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
    9198           0 : 
    9199             :   // Try to match the instruction in an extension of the current IT block (if
    9200             :   // there is one).
    9201             :   if (inImplicitITBlock()) {
    9202             :     extendImplicitITBlock(ITState.Cond);
    9203             :     if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
    9204           0 :             Match_Success) {
    9205           0 :       // The match succeded, but we still have to check that the instruction is
    9206             :       // valid in this implicit IT block.
    9207             :       const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
    9208           0 :       if (MCID.isPredicable()) {
    9209           0 :         ARMCC::CondCodes InstCond =
    9210             :             (ARMCC::CondCodes)Inst.getOperand(MCID.findFirstPredOperandIdx())
    9211             :                 .getImm();
    9212             :         ARMCC::CondCodes ITCond = currentITCond();
    9213             :         if (InstCond == ITCond) {
    9214             :           EmitInITBlock = true;
    9215             :           return Match_Success;
    9216       25518 :         } else if (InstCond == ARMCC::getOppositeCondition(ITCond)) {
    9217             :           invertCurrentITCondition();
    9218             :           EmitInITBlock = true;
    9219             :           return Match_Success;
    9220             :         }
    9221             :       }
    9222       22451 :     }
    9223       25382 :     rewindImplicitITPosition();
    9224             :   }
    9225             : 
    9226             :   // Finish the current IT block, and try to match outside any IT block.
    9227             :   flushPendingInstructions(Out);
    9228             :   unsigned PlainMatchResult =
    9229          29 :       MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
    9230             :   if (PlainMatchResult == Match_Success) {
    9231             :     const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
    9232             :     if (MCID.isPredicable()) {
    9233          29 :       ARMCC::CondCodes InstCond =
    9234          58 :           (ARMCC::CondCodes)Inst.getOperand(MCID.findFirstPredOperandIdx())
    9235             :               .getImm();
    9236          25 :       // Some forms of the branch instruction have their own condition code
    9237          25 :       // fields, so can be conditionally executed without an IT block.
    9238             :       if (Inst.getOpcode() == ARM::tBcc || Inst.getOpcode() == ARM::t2Bcc) {
    9239          25 :         EmitInITBlock = false;
    9240          15 :         return Match_Success;
    9241          15 :       }
    9242          10 :       if (InstCond == ARMCC::AL) {
    9243             :         EmitInITBlock = false;
    9244           5 :         return Match_Success;
    9245           5 :       }
    9246             :     } else {
    9247             :       EmitInITBlock = false;
    9248             :       return Match_Success;
    9249             :     }
    9250             :   }
    9251             : 
    9252             :   // Try to match in a new IT block. The matcher doesn't check the actual
    9253         116 :   // condition, so we create an IT block with a dummy condition, and fix it up
    9254             :   // once we know the actual condition.
    9255         116 :   startImplicitITBlock();
    9256         116 :   if (MatchInstructionImpl(Operands, Inst, nullptr, MatchingInlineAsm) ==
    9257         116 :       Match_Success) {
    9258         232 :     const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
    9259             :     if (MCID.isPredicable()) {
    9260         103 :       ITState.Cond =
    9261         103 :           (ARMCC::CondCodes)Inst.getOperand(MCID.findFirstPredOperandIdx())
    9262             :               .getImm();
    9263             :       EmitInITBlock = true;
    9264         103 :       return Match_Success;
    9265           4 :     }
    9266           4 :   }
    9267             :   discardImplicitITBlock();
    9268          99 : 
    9269           5 :   // If none of these succeed, return the error we got when trying to match
    9270           5 :   // outside any IT blocks.
    9271             :   EmitInITBlock = false;
    9272             :   return PlainMatchResult;
    9273          13 : }
    9274          13 : 
    9275             : static std::string ARMMnemonicSpellCheck(StringRef S, uint64_t FBS,
    9276             :                                          unsigned VariantID = 0);
    9277             : 
    9278             : static const char *getSubtargetFeatureName(uint64_t Val);
    9279             : bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
    9280             :                                            OperandVector &Operands,
    9281             :                                            MCStreamer &Out, uint64_t &ErrorInfo,
    9282          94 :                                            bool MatchingInlineAsm) {
    9283             :   MCInst Inst;
    9284          94 :   unsigned MatchResult;
    9285         188 :   bool PendConditionalInstruction = false;
    9286          94 : 
    9287          94 :   SmallVector<NearMissInfo, 4> NearMisses;
    9288          94 :   MatchResult = MatchInstruction(Operands, Inst, NearMisses, MatchingInlineAsm,
    9289          94 :                                  PendConditionalInstruction, Out);
    9290          94 : 
    9291             :   switch (MatchResult) {
    9292             :   case Match_Success:
    9293             :     // Context sensitive operand constraints aren't handled by the matcher,
    9294             :     // so check them here.
    9295             :     if (validateInstruction(Inst, Operands)) {
    9296             :       // Still progress the IT block, otherwise one wrong condition causes
    9297           0 :       // nasty cascading errors.
    9298           0 :       forwardITPosition();
    9299             :       return true;
    9300             :     }
    9301             : 
    9302             :     { // processInstruction() updates inITBlock state, we need to save it away
    9303             :       bool wasInITBlock = inITBlock();
    9304             : 
    9305       25518 :       // Some instructions need post-processing to, for example, tweak which
    9306             :       // encoding is selected. Loop on it while changes happen so the
    9307             :       // individual transformations can chain off each other. E.g.,
    9308             :       // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
    9309             :       while (processInstruction(Inst, Operands, Out))
    9310             :         ;
    9311       25518 : 
    9312             :       // Only after the instruction is fully processed, we can validate it
    9313             :       if (wasInITBlock && hasV8Ops() && isThumb() &&
    9314       25518 :           !isV8EligibleForIT(&Inst)) {
    9315             :         Warning(IDLoc, "deprecated instruction in IT block");
    9316             :       }
    9317       25518 :     }
    9318       21193 : 
    9319             :     // Only move forward at the very end so that everything in validate
    9320             :     // and process gets a consistent answer about whether we're in an IT
    9321       21193 :     // block.
    9322             :     forwardITPosition();
    9323             : 
    9324             :     // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
    9325         401 :     // doesn't actually encode.
    9326             :     if (Inst.getOpcode() == ARM::ITasm)
    9327             :       return false;
    9328             : 
    9329       20792 :     Inst.setLoc(IDLoc);
    9330             :     if (PendConditionalInstruction) {
    9331             :       PendingConditionalInsts.push_back(Inst);
    9332             :       if (isITBlockFull() || isITBlockTerminator(Inst))
    9333             :         flushPendingInstructions(Out);
    9334             :     } else {
    9335       22359 :       Out.EmitInstruction(Inst, getSTI());
    9336             :     }
    9337             :     return false;
    9338             :   case Match_NearMisses:
    9339       26098 :     ReportNearMisses(NearMisses, IDLoc, Operands);
    9340        2206 :     return true;
    9341        2147 :   case Match_MnemonicFail: {
    9342             :     uint64_t FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
    9343             :     std::string Suggestion = ARMMnemonicSpellCheck(
    9344             :       ((ARMOperand &)*Operands[0]).getToken(), FBS);
    9345             :     return Error(IDLoc, "invalid instruction" + Suggestion,
    9346             :                  ((ARMOperand &)*Operands[0]).getLocRange());
    9347             :   }
    9348             :   }
    9349             : 
    9350             :   llvm_unreachable("Implement any new match types added!");
    9351             : }
    9352       20792 : 
    9353             : /// parseDirective parses the arm specific directives
    9354             : bool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
    9355             :   const MCObjectFileInfo::Environment Format =
    9356       20738 :     getContext().getObjectFileInfo()->getObjectFileType();
    9357         114 :   bool IsMachO = Format == MCObjectFileInfo::IsMachO;
    9358         110 :   bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
    9359          34 : 
    9360             :   StringRef IDVal = DirectiveID.getIdentifier();
    9361       20624 :   if (IDVal == ".word")
    9362             :     parseLiteralValues(4, DirectiveID.getLoc());
    9363             :   else if (IDVal == ".short" || IDVal == ".hword")
    9364        4299 :     parseLiteralValues(2, DirectiveID.getLoc());
    9365        4299 :   else if (IDVal == ".thumb")
    9366        4299 :     parseDirectiveThumb(DirectiveID.getLoc());
    9367          26 :   else if (IDVal == ".arm")
    9368          26 :     parseDirectiveARM(DirectiveID.getLoc());
    9369             :   else if (IDVal == ".thumb_func")
    9370          26 :     parseDirectiveThumbFunc(DirectiveID.getLoc());
    9371          78 :   else if (IDVal == ".code")
    9372             :     parseDirectiveCode(DirectiveID.getLoc());
    9373             :   else if (IDVal == ".syntax")
    9374             :     parseDirectiveSyntax(DirectiveID.getLoc());
    9375             :   else if (IDVal == ".unreq")
    9376           0 :     parseDirectiveUnreq(DirectiveID.getLoc());
    9377             :   else if (IDVal == ".fnend")
    9378             :     parseDirectiveFnEnd(DirectiveID.getLoc());
    9379             :   else if (IDVal == ".cantunwind")
    9380       10356 :     parseDirectiveCantUnwind(DirectiveID.getLoc());
    9381             :   else if (IDVal == ".personality")
    9382       10356 :     parseDirectivePersonality(DirectiveID.getLoc());
    9383             :   else if (IDVal == ".handlerdata")
    9384             :     parseDirectiveHandlerData(DirectiveID.getLoc());
    9385             :   else if (IDVal == ".setfp")
    9386             :     parseDirectiveSetFP(DirectiveID.getLoc());
    9387             :   else if (IDVal == ".pad")
    9388        2264 :     parseDirectivePad(DirectiveID.getLoc());
    9389             :   else if (IDVal == ".save")
    9390          47 :     parseDirectiveRegSave(DirectiveID.getLoc(), false);
    9391             :   else if (IDVal == ".vsave")
    9392         421 :     parseDirectiveRegSave(DirectiveID.getLoc(), true);
    9393             :   else if (IDVal == ".ltorg" || IDVal == ".pool")
    9394         115 :     parseDirectiveLtorg(DirectiveID.getLoc());
    9395             :   else if (IDVal == ".even")
    9396         132 :     parseDirectiveEven(DirectiveID.getLoc());
    9397             :   else if (IDVal == ".personalityindex")
    9398         130 :     parseDirectivePersonalityIndex(DirectiveID.getLoc());
    9399             :   else if (IDVal == ".unwind_raw")
    9400         371 :     parseDirectiveUnwindRaw(DirectiveID.getLoc());
    9401             :   else if (IDVal == ".movsp")
    9402           7 :     parseDirectiveMovSP(DirectiveID.getLoc());
    9403             :   else if (IDVal == ".arch_extension")
    9404         228 :     parseDirectiveArchExtension(DirectiveID.getLoc());
    9405             :   else if (IDVal == ".align")
    9406          58 :     return parseDirectiveAlign(DirectiveID.getLoc()); // Use Generic on failure.
    9407             :   else if (IDVal == ".thumb_set")
    9408          80 :     parseDirectiveThumbSet(DirectiveID.getLoc());
    9409             :   else if (IDVal == ".inst")
    9410          79 :     parseDirectiveInst(DirectiveID.getLoc());
    9411             :   else if (IDVal == ".inst.n")
    9412          42 :     parseDirectiveInst(DirectiveID.getLoc(), 'n');
    9413             :   else if (IDVal == ".inst.w")
    9414          30 :     parseDirectiveInst(DirectiveID.getLoc(), 'w');
    9415             :   else if (!IsMachO && !IsCOFF) {
    9416          47 :     if (IDVal == ".arch")
    9417             :       parseDirectiveArch(DirectiveID.getLoc());
    9418          17 :     else if (IDVal == ".cpu")
    9419             :       parseDirectiveCPU(DirectiveID.getLoc());
    9420          48 :     else if (IDVal == ".eabi_attribute")
    9421             :       parseDirectiveEabiAttr(DirectiveID.getLoc());
    9422           8 :     else if (IDVal == ".fpu")
    9423             :       parseDirectiveFPU(DirectiveID.getLoc());
    9424          19 :     else if (IDVal == ".fnstart")
    9425             :       parseDirectiveFnStart(DirectiveID.getLoc());
    9426          64 :     else if (IDVal == ".object_arch")
    9427             :       parseDirectiveObjectArch(DirectiveID.getLoc());
    9428          13 :     else if (IDVal == ".tlsdescseq")
    9429             :       parseDirectiveTLSDescSeq(DirectiveID.getLoc());
    9430          80 :     else
    9431             :       return true;
    9432         194 :   } else
    9433             :     return true;
    9434          30 :   return false;
    9435             : }
    9436          13 : 
    9437             : /// parseLiteralValues
    9438          14 : ///  ::= .hword expression [, expression]*
    9439             : ///  ::= .short expression [, expression]*
    9440          17 : ///  ::= .word expression [, expression]*
    9441        5788 : bool ARMAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
    9442             :   auto parseOne = [&]() -> bool {
    9443          96 :     const MCExpr *Value;
    9444             :     if (getParser().parseExpression(Value))
    9445          22 :       return true;
    9446             :     getParser().getStreamer().EmitValue(Value, Size, L);
    9447         724 :     return false;
    9448             :   };
    9449          58 :   return (parseMany(parseOne));
    9450             : }
    9451         233 : 
    9452             : /// parseDirectiveThumb
    9453          10 : ///  ::= .thumb
    9454             : bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
    9455          13 :   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") ||
    9456             :       check(!hasThumb(), L, "target does not support Thumb mode"))
    9457             :     return true;
    9458             : 
    9459             :   if (!isThumb())
    9460             :     SwitchMode();
    9461             : 
    9462             :   getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
    9463             :   return false;
    9464             : }
    9465             : 
    9466             : /// parseDirectiveARM
    9467             : ///  ::= .arm
    9468             : bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
    9469             :   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive") ||
    9470             :       check(!hasARM(), L, "target does not support ARM mode"))
    9471             :     return true;
    9472             : 
    9473             :   if (isThumb())
    9474        2311 :     SwitchMode();
    9475        2311 :   getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
    9476             :   return false;
    9477             : }
    9478             : 
    9479             : void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol) {
    9480         421 :   // We need to flush the current implicit IT block on a label, because it is
    9481         421 :   // not legal to branch into an IT block.
    9482         419 :   flushPendingInstructions(getStreamer());
    9483           3 : }
    9484             : 
    9485         418 : void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) {
    9486         126 :   if (NextSymbolIsThumb) {
    9487             :     getParser().getStreamer().EmitThumbFunc(Symbol);
    9488         418 :     NextSymbolIsThumb = false;
    9489         418 :   }
    9490             : }
    9491             : 
    9492             : /// parseDirectiveThumbFunc
    9493             : ///  ::= .thumbfunc symbol_name
    9494         115 : bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
    9495         115 :   MCAsmParser &Parser = getParser();
    9496         113 :   const auto Format = getContext().getObjectFileInfo()->getObjectFileType();
    9497          10 :   bool IsMachO = Format == MCObjectFileInfo::IsMachO;
    9498             : 
    9499         105 :   // Darwin asm has (optionally) function name after .thumb_func direction
    9500          70 :   // ELF doesn't
    9501         105 : 
    9502         105 :   if (IsMachO) {
    9503             :     if (Parser.getTok().is(AsmToken::Identifier) ||
    9504             :         Parser.getTok().is(AsmToken::String)) {
    9505        1920 :       MCSymbol *Func = getParser().getContext().getOrCreateSymbol(
    9506             :           Parser.getTok().getIdentifier());
    9507             :       getParser().getStreamer().EmitThumbFunc(Func);
    9508        1920 :       Parser.Lex();
    9509        1920 :       if (parseToken(AsmToken::EndOfStatement,
    9510             :                      "unexpected token in '.thumb_func' directive"))
    9511        1920 :         return true;
    9512        1920 :       return false;
    9513          84 :     }
    9514          84 :   }
    9515             : 
    9516        1920 :   if (parseToken(AsmToken::EndOfStatement,
    9517             :                  "unexpected token in '.thumb_func' directive"))
    9518             :     return true;
    9519             : 
    9520           0 :   NextSymbolIsThumb = true;
    9521           0 :   return false;
    9522           0 : }
    9523             : 
    9524             : /// parseDirectiveSyntax
    9525             : ///  ::= .syntax unified | divided
    9526             : bool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
    9527             :   MCAsmParser &Parser = getParser();
    9528           0 :   const AsmToken &Tok = Parser.getTok();
    9529           0 :   if (Tok.isNot(AsmToken::Identifier)) {
    9530           0 :     Error(L, "unexpected token in .syntax directive");
    9531           0 :     return false;
    9532           0 :   }
    9533           0 : 
    9534           0 :   StringRef Mode = Tok.getString();
    9535           0 :   Parser.Lex();
    9536             :   if (check(Mode == "divided" || Mode == "DIVIDED", L,
    9537           0 :             "'.syntax divided' arm assembly not supported") ||
    9538           0 :       check(Mode != "unified" && Mode != "UNIFIED", L,
    9539             :             "unrecognized syntax mode in .syntax directive") ||
    9540             :       parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
    9541             :     return true;
    9542           0 : 
    9543             :   // TODO tell the MC streamer the mode
    9544           0 :   // getParser().getStreamer().Emit???();
    9545             :   return false;
    9546           0 : }
    9547           0 : 
    9548             : /// parseDirectiveCode
    9549             : ///  ::= .code 16 | 32
    9550             : bool ARMAsmParser::parseDirectiveCode(SMLoc L) {
    9551             :   MCAsmParser &Parser = getParser();
    9552         371 :   const AsmToken &Tok = Parser.getTok();
    9553         371 :   if (Tok.isNot(AsmToken::Integer))
    9554         371 :     return Error(L, "unexpected token in .code directive");
    9555         371 :   int64_t Val = Parser.getTok().getIntVal();
    9556           0 :   if (Val != 16 && Val != 32) {
    9557           0 :     Error(L, "invalid operand to .code directive");
    9558             :     return false;
    9559             :   }
    9560             :   Parser.Lex();
    9561         371 : 
    9562         371 :   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
    9563         371 :     return true;
    9564         371 : 
    9565         742 :   if (Val == 16) {
    9566         369 :     if (!hasThumb())
    9567           2 :       return Error(L, "target does not support Thumb mode");
    9568             : 
    9569             :     if (!isThumb())
    9570             :       SwitchMode();
    9571             :     getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
    9572             :   } else {
    9573             :     if (!hasARM())
    9574             :       return Error(L, "target does not support ARM mode");
    9575             : 
    9576         130 :     if (isThumb())
    9577         130 :       SwitchMode();
    9578         130 :     getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
    9579         130 :   }
    9580           0 : 
    9581         130 :   return false;
    9582         130 : }
    9583           0 : 
    9584           0 : /// parseDirectiveReq
    9585             : ///  ::= name .req registername
    9586         130 : bool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
    9587             :   MCAsmParser &Parser = getParser();
    9588         130 :   Parser.Lex(); // Eat the '.req' token.
    9589             :   unsigned Reg;
    9590             :   SMLoc SRegLoc, ERegLoc;
    9591         128 :   if (check(ParseRegister(Reg, SRegLoc, ERegLoc), SRegLoc,
    9592          85 :             "register name expected") ||
    9593           1 :       parseToken(AsmToken::EndOfStatement,
    9594             :                  "unexpected input in .req directive."))
    9595          84 :     return true;
    9596          31 : 
    9597          84 :   if (RegisterReqs.insert(std::make_pair(Name, Reg)).first->second != Reg)
    9598             :     return Error(SRegLoc,
    9599          43 :                  "redefinition of '" + Name + "' does not match original.");
    9600           5 : 
    9601             :   return false;
    9602          38 : }
    9603          23 : 
    9604          38 : /// parseDirectiveUneq
    9605             : ///  ::= .unreq registername
    9606             : bool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
    9607             :   MCAsmParser &Parser = getParser();
    9608             :   if (Parser.getTok().isNot(AsmToken::Identifier))
    9609             :     return Error(L, "unexpected input in .unreq directive.");
    9610             :   RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
    9611             :   Parser.Lex(); // Eat the identifier.
    9612           0 :   if (parseToken(AsmToken::EndOfStatement,
    9613           0 :                  "unexpected input in '.unreq' directive"))
    9614           0 :     return true;
    9615             :   return false;
    9616           0 : }
    9617           0 : 
    9618           0 : // After changing arch/CPU, try to put the ARM/Thumb mode back to what it was
    9619           0 : // before, if supported by the new target, or emit mapping symbols for the mode
    9620             : // switch.
    9621           0 : void ARMAsmParser::FixModeAfterArchChange(bool WasThumb, SMLoc Loc) {
    9622             :   if (WasThumb != isThumb()) {
    9623           0 :     if (WasThumb && hasThumb()) {
    9624           0 :       // Stay in Thumb mode
    9625           0 :       SwitchMode();
    9626             :     } else if (!WasThumb && hasARM()) {
    9627             :       // Stay in ARM mode
    9628             :       SwitchMode();
    9629             :     } else {
    9630             :       // Mode switch forced, because the new arch doesn't support the old mode.
    9631             :       getParser().getStreamer().EmitAssemblerFlag(isThumb() ? MCAF_Code16
    9632           7 :                                                             : MCAF_Code32);
    9633           7 :       // Warn about the implcit mode switch. GAS does not switch modes here,
    9634           7 :       // but instead stays in the old mode, reporting an error on any following
    9635           0 :       // instructions as the mode does not exist on the target.
    9636          14 :       Warning(Loc, Twine("new target does not support ") +
    9637           7 :                        (WasThumb ? "thumb" : "arm") + " mode, switching to " +
    9638           7 :                        (!WasThumb ? "thumb" : "arm") + " mode");
    9639             :     }
    9640           2 :   }
    9641             : }
    9642             : 
    9643             : /// parseDirectiveArch
    9644             : ///  ::= .arch token
    9645             : bool ARMAsmParser::parseDirectiveArch(SMLoc L) {
    9646             :   StringRef Arch = getParser().parseStringToEndOfStatement().trim();
    9647         115 :   ARM::ArchKind ID = ARM::parseArch(Arch);
    9648         115 : 
    9649          27 :   if (ID == ARM::ArchKind::INVALID)
    9650             :     return Error(L, "Unknown arch name");
    9651           7 : 
    9652          26 :   bool WasThumb = isThumb();
    9653             :   Triple T;
    9654           0 :   MCSubtargetInfo &STI = copySTI();
    9655             :   STI.setDefaultFeatures("", ("+" + ARM::getArchName(ID)).str());
    9656             :   setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
    9657          26 :   FixModeAfterArchChange(WasThumb, L);
    9658          13 : 
    9659             :   getTargetStreamer().emitArch(ID);
    9660             :   return false;
    9661             : }
    9662          26 : 
    9663          13 : /// parseDirectiveEabiAttr
    9664          26 : ///  ::= .eabi_attribute int, int [, "str"]
    9665             : ///  ::= .eabi_attribute Tag_name, int [, "str"]
    9666             : bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
    9667         115 :   MCAsmParser &Parser = getParser();
    9668             :   int64_t Tag;
    9669             :   SMLoc TagLoc;
    9670             :   TagLoc = Parser.getTok().getLoc();
    9671          96 :   if (Parser.getTok().is(AsmToken::Identifier)) {
    9672          96 :     StringRef Name = Parser.getTok().getIdentifier();
    9673          96 :     Tag = ARMBuildAttrs::AttrTypeFromString(Name);
    9674             :     if (Tag == -1) {
    9675          96 :       Error(TagLoc, "attribute name not recognised: " + Name);
    9676           1 :       return false;
    9677             :     }
    9678             :     Parser.Lex();
    9679             :   } else {
    9680          95 :     const MCExpr *AttrExpr;
    9681          95 : 
    9682          95 :     TagLoc = Parser.getTok().getLoc();
    9683          95 :     if (Parser.parseExpression(AttrExpr))
    9684             :       return true;
    9685          95 : 
    9686             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
    9687             :     if (check(!CE, TagLoc, "expected numeric constant"))
    9688             :       return true;
    9689             : 
    9690             :     Tag = CE->getValue();
    9691             :   }
    9692           0 : 
    9693           0 :   if (Parser.parseToken(AsmToken::Comma, "comma expected"))
    9694             :     return true;
    9695             : 
    9696           0 :   StringRef StringValue = "";
    9697           0 :   bool IsStringValue = false;
    9698           0 : 
    9699           0 :   int64_t IntegerValue = 0;
    9700           0 :   bool IsIntegerValue = false;
    9701           0 : 
    9702           0 :   if (Tag == ARMBuildAttrs::CPU_raw_name || Tag == ARMBuildAttrs::CPU_name)
    9703             :     IsStringValue = true;
    9704           0 :   else if (Tag == ARMBuildAttrs::compatibility) {
    9705             :     IsStringValue = true;
    9706             :     IsIntegerValue = true;
    9707             :   } else if (Tag < 32 || Tag % 2 == 0)
    9708           0 :     IsIntegerValue = true;
    9709           0 :   else if (Tag % 2 == 1)
    9710           0 :     IsStringValue = true;
    9711             :   else
    9712           0 :     llvm_unreachable("invalid tag type");
    9713           0 : 
    9714           0 :   if (IsIntegerValue) {
    9715             :     const MCExpr *ValueExpr;
    9716           0 :     SMLoc ValueExprLoc = Parser.getTok().getLoc();
    9717             :     if (Parser.parseExpression(ValueExpr))
    9718             :       return true;
    9719           0 : 
    9720           0 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
    9721             :     if (!CE)
    9722             :       return Error(ValueExprLoc, "expected numeric constant");
    9723             :     IntegerValue = CE->getValue();
    9724             :   }
    9725             : 
    9726             :   if (Tag == ARMBuildAttrs::compatibility) {
    9727             :     if (Parser.parseToken(AsmToken::Comma, "comma expected"))
    9728           0 :       return true;
    9729             :   }
    9730           0 : 
    9731             :   if (IsStringValue) {
    9732             :     if (Parser.getTok().isNot(AsmToken::String))
    9733           0 :       return Error(Parser.getTok().getLoc(), "bad string constant");
    9734             : 
    9735           0 :     StringValue = Parser.getTok().getStringContents();
    9736             :     Parser.Lex();
    9737             :   }
    9738           0 : 
    9739             :   if (Parser.parseToken(AsmToken::EndOfStatement,
    9740             :                         "unexpected token in '.eabi_attribute' directive"))
    9741             :     return true;
    9742           0 : 
    9743           0 :   if (IsIntegerValue && IsStringValue) {
    9744           0 :     assert(Tag == ARMBuildAttrs::compatibility);
    9745             :     getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue);
    9746           0 :   } else if (IsIntegerValue)
    9747             :     getTargetStreamer().emitAttribute(Tag, IntegerValue);
    9748           0 :   else if (IsStringValue)
    9749           0 :     getTargetStreamer().emitTextAttribute(Tag, StringValue);
    9750             :   return false;
    9751             : }
    9752           0 : 
    9753           0 : /// parseDirectiveCPU
    9754           0 : ///  ::= .cpu str
    9755             : bool ARMAsmParser::parseDirectiveCPU(SMLoc L) {
    9756             :   StringRef CPU = getParser().parseStringToEndOfStatement().trim();
    9757           0 :   getTargetStreamer().emitTextAttribute(ARMBuildAttrs::CPU_name, CPU);
    9758           0 : 
    9759           0 :   // FIXME: This is using table-gen data, but should be moved to
    9760             :   // ARMTargetParser once that is table-gen'd.
    9761           0 :   if (!getSTI().isCPUStringValid(CPU))
    9762           0 :     return Error(L, "Unknown CPU name");
    9763             : 
    9764             :   bool WasThumb = isThumb();
    9765           0 :   MCSubtargetInfo &STI = copySTI();
    9766             :   STI.setDefaultFeatures(CPU, "");
    9767           0 :   setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
    9768             :   FixModeAfterArchChange(WasThumb, L);
    9769           0 : 
    9770             :   return false;
    9771           0 : }
    9772           0 : 
    9773           0 : /// parseDirectiveFPU
    9774           0 : ///  ::= .fpu str
    9775           0 : bool ARMAsmParser::parseDirectiveFPU(SMLoc L) {
    9776             :   SMLoc FPUNameLoc = getTok().getLoc();
    9777             :   StringRef FPU = getParser().parseStringToEndOfStatement().trim();
    9778             : 
    9779             :   unsigned ID = ARM::parseFPU(FPU);
    9780             :   std::vector<StringRef> Features;
    9781          22 :   if (!ARM::getFPUFeatures(ID, Features))
    9782          44 :     return Error(FPUNameLoc, "Unknown FPU name");
    9783          22 : 
    9784             :   MCSubtargetInfo &STI = copySTI();
    9785             :   for (auto Feature : Features)
    9786             :     STI.ApplyFeatureFlag(Feature);
    9787          22 :   setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
    9788           2 : 
    9789             :   getTargetStreamer().emitFPU(ID);
    9790             :   return false;
    9791          20 : }
    9792          20 : 
    9793          20 : /// parseDirectiveFnStart
    9794          20 : ///  ::= .fnstart
    9795             : bool ARMAsmParser::parseDirectiveFnStart(SMLoc L) {
    9796          20 :   if (parseToken(AsmToken::EndOfStatement,
    9797             :                  "unexpected token in '.fnstart' directive"))
    9798             :     return true;
    9799             : 
    9800             :   if (UC.hasFnStart()) {
    9801           0 :     Error(L, ".fnstart starts before the end of previous one");
    9802           0 :     UC.emitFnStartLocNotes();
    9803           0 :     return true;
    9804             :   }
    9805           0 : 
    9806             :   // Reset the unwind directives parser state
    9807           0 :   UC.reset();
    9808           0 : 
    9809             :   getTargetStreamer().emitFnStart();
    9810           0 : 
    9811           0 :   UC.recordFnStart(L);
    9812           0 :   return false;
    9813           0 : }
    9814             : 
    9815           0 : /// parseDirectiveFnEnd
    9816           0 : ///  ::= .fnend
    9817             : bool ARMAsmParser::parseDirectiveFnEnd(SMLoc L) {
    9818             :   if (parseToken(AsmToken::EndOfStatement,
    9819             :                  "unexpected token in '.fnend' directive"))
    9820             :     return true;
    9821         233 :   // Check the ordering of unwind directives
    9822         233 :   if (!UC.hasFnStart())
    9823             :     return Error(L, ".fnstart must precede .fnend directive");
    9824             : 
    9825             :   // Reset the unwind directives parser state
    9826         231 :   getTargetStreamer().emitFnEnd();
    9827           1 : 
    9828           1 :   UC.reset();
    9829           1 :   return false;
    9830             : }
    9831             : 
    9832             : /// parseDirectiveCantUnwind
    9833         230 : ///  ::= .cantunwind
    9834             : bool ARMAsmParser::parseDirectiveCantUnwind(SMLoc L) {
    9835         230 :   if (parseToken(AsmToken::EndOfStatement,
    9836             :                  "unexpected token in '.cantunwind' directive"))
    9837         230 :     return true;
    9838         230 : 
    9839             :   UC.recordCantUnwind(L);
    9840             :   // Check the ordering of unwind directives
    9841             :   if (check(!UC.hasFnStart(), L, ".fnstart must precede .cantunwind directive"))
    9842             :     return true;
    9843         228 : 
    9844         228 :   if (UC.hasHandlerData()) {
    9845             :     Error(L, ".cantunwind can't be used with .handlerdata directive");
    9846             :     UC.emitHandlerDataLocNotes();
    9847             :     return true;
    9848         226 :   }
    9849           1 :   if (UC.hasPersonality()) {
    9850             :     Error(L, ".cantunwind can't be used with .personality directive");
    9851             :     UC.emitPersonalityLocNotes();
    9852         225 :     return true;
    9853             :   }
    9854         225 : 
    9855         225 :   getTargetStreamer().emitCantUnwind();
    9856             :   return false;
    9857             : }
    9858             : 
    9859             : /// parseDirectivePersonality
    9860          58 : ///  ::= .personality name
    9861          58 : bool ARMAsmParser::parseDirectivePersonality(SMLoc L) {
    9862             :   MCAsmParser &Parser = getParser();
    9863             :   bool HasExistingPersonality = UC.hasPersonality();
    9864             : 
    9865          56 :   // Parse the name of the personality routine
    9866             :   if (Parser.getTok().isNot(AsmToken::Identifier))
    9867          56 :     return Error(L, "unexpected input in .personality directive.");
    9868             :   StringRef Name(Parser.getTok().getIdentifier());
    9869             :   Parser.Lex();
    9870          55 : 
    9871           1 :   if (parseToken(AsmToken::EndOfStatement,
    9872           1 :                  "unexpected token in '.personality' directive"))
    9873           1 :     return true;
    9874             : 
    9875             :   UC.recordPersonality(L);
    9876           2 : 
    9877           2 :   // Check the ordering of unwind directives
    9878           2 :   if (!UC.hasFnStart())
    9879             :     return Error(L, ".fnstart must precede .personality directive");
    9880             :   if (UC.cantUnwind()) {
    9881          52 :     Error(L, ".personality can't be used with .cantunwind directive");
    9882          52 :     UC.emitCantUnwindLocNotes();
    9883             :     return true;
    9884             :   }
    9885             :   if (UC.hasHandlerData()) {
    9886             :     Error(L, ".personality must precede .handlerdata directive");
    9887          80 :     UC.emitHandlerDataLocNotes();
    9888          80 :     return true;
    9889             :   }
    9890             :   if (HasExistingPersonality) {
    9891             :     Error(L, "multiple personality directives");
    9892          80 :     UC.emitPersonalityLocNotes();
    9893           0 :     return true;
    9894          80 :   }
    9895          80 : 
    9896             :   MCSymbol *PR = getParser().getContext().getOrCreateSymbol(Name);
    9897          80 :   getTargetStreamer().emitPersonality(PR);
    9898             :   return false;
    9899             : }
    9900             : 
    9901          78 : /// parseDirectiveHandlerData
    9902             : ///  ::= .handlerdata
    9903             : bool ARMAsmParser::parseDirectiveHandlerData(SMLoc L) {
    9904          78 :   if (parseToken(AsmToken::EndOfStatement,
    9905           1 :                  "unexpected token in '.handlerdata' directive"))
    9906          77 :     return true;
    9907           1 : 
    9908           1 :   UC.recordHandlerData(L);
    9909           1 :   // Check the ordering of unwind directives
    9910             :   if (!UC.hasFnStart())
    9911          76 :     return Error(L, ".fnstart must precede .personality directive");
    9912           1 :   if (UC.cantUnwind()) {
    9913           1 :     Error(L, ".handlerdata can't be used with .cantunwind directive");
    9914           1 :     UC.emitCantUnwindLocNotes();
    9915             :     return true;
    9916          75 :   }
    9917           2 : 
    9918           2 :   getTargetStreamer().emitHandlerData();
    9919           2 :   return false;
    9920             : }
    9921             : 
    9922          73 : /// parseDirectiveSetFP
    9923          73 : ///  ::= .setfp fpreg, spreg [, offset]
    9924          73 : bool ARMAsmParser::parseDirectiveSetFP(SMLoc L) {
    9925             :   MCAsmParser &Parser = getParser();
    9926             :   // Check the ordering of unwind directives
    9927             :   if (check(!UC.hasFnStart(), L, ".fnstart must precede .setfp directive") ||
    9928             :       check(UC.hasHandlerData(), L,
    9929          79 :             ".setfp must precede .handlerdata directive"))
    9930          79 :     return true;
    9931             : 
    9932             :   // Parse fpreg
    9933             :   SMLoc FPRegLoc = Parser.getTok().getLoc();
    9934          77 :   int FPReg = tryParseRegister();
    9935             : 
    9936          77 :   if (check(FPReg == -1, FPRegLoc, "frame pointer register expected") ||
    9937           0 :       Parser.parseToken(AsmToken::Comma, "comma expected"))
    9938          77 :     return true;
    9939           1 : 
    9940           1 :   // Parse spreg
    9941           1 :   SMLoc SPRegLoc = Parser.getTok().getLoc();
    9942             :   int SPReg = tryParseRegister();
    9943             :   if (check(SPReg == -1, SPRegLoc, "stack pointer register expected") ||
    9944          76 :       check(SPReg != ARM::SP && SPReg != UC.getFPReg(), SPRegLoc,
    9945          76 :             "register should be either $sp or the latest fp register"))
    9946             :     return true;
    9947             : 
    9948             :   // Update the frame pointer register
    9949             :   UC.saveFPReg(FPReg);
    9950          42 : 
    9951          42 :   // Parse offset
    9952             :   int64_t Offset = 0;
    9953          42 :   if (Parser.parseOptionalToken(AsmToken::Comma)) {
    9954          41 :     if (Parser.getTok().isNot(AsmToken::Hash) &&
    9955             :         Parser.getTok().isNot(AsmToken::Dollar))
    9956           2 :       return Error(Parser.getTok().getLoc(), "'#' expected");
    9957             :     Parser.Lex(); // skip hash token.
    9958             : 
    9959          40 :     const MCExpr *OffsetExpr;
    9960          40 :     SMLoc ExLoc = Parser.getTok().getLoc();
    9961             :     SMLoc EndLoc;
    9962          79 :     if (getParser().parseExpression(OffsetExpr, EndLoc))
    9963          39 :       return Error(ExLoc, "malformed setfp offset");
    9964           1 :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
    9965             :     if (check(!CE, ExLoc, "setfp offset must be an immediate"))
    9966             :       return true;
    9967          39 :     Offset = CE->getValue();
    9968          39 :   }
    9969          39 : 
    9970          39 :   if (Parser.parseToken(AsmToken::EndOfStatement))
    9971             :     return true;
    9972           2 : 
    9973             :   getTargetStreamer().emitSetFP(static_cast<unsigned>(FPReg),
    9974             :                                 static_cast<unsigned>(SPReg), Offset);
    9975             :   return false;
    9976             : }
    9977             : 
    9978             : /// parseDirective
    9979          37 : ///  ::= .pad offset
    9980          32 : bool ARMAsmParser::parseDirectivePad(SMLoc L) {
    9981           0 :   MCAsmParser &Parser = getParser();
    9982           0 :   // Check the ordering of unwind directives
    9983          32 :   if (!UC.hasFnStart())
    9984             :     return Error(L, ".fnstart must precede .pad directive");
    9985             :   if (UC.hasHandlerData())
    9986          32 :     return Error(L, ".pad must precede .handlerdata directive");
    9987          32 : 
    9988          32 :   // Parse the offset
    9989           0 :   if (Parser.getTok().isNot(AsmToken::Hash) &&
    9990          32 :       Parser.getTok().isNot(AsmToken::Dollar))
    9991          32 :     return Error(Parser.getTok().getLoc(), "'#' expected");
    9992             :   Parser.Lex(); // skip hash token.
    9993          32 : 
    9994             :   const MCExpr *OffsetExpr;
    9995             :   SMLoc ExLoc = Parser.getTok().getLoc();
    9996          37 :   SMLoc EndLoc;
    9997             :   if (getParser().parseExpression(OffsetExpr, EndLoc))
    9998             :     return Error(ExLoc, "malformed pad offset");
    9999          35 :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
   10000          35 :   if (!CE)
   10001          35 :     return Error(ExLoc, "pad offset must be an immediate");
   10002             : 
   10003             :   if (parseToken(AsmToken::EndOfStatement,
   10004             :                  "unexpected token in '.pad' directive"))
   10005             :     return true;
   10006          30 : 
   10007          30 :   getTargetStreamer().emitPad(CE->getValue());
   10008             :   return false;
   10009          30 : }
   10010           1 : 
   10011          29 : /// parseDirectiveRegSave
   10012           1 : ///  ::= .save  { registers }
   10013             : ///  ::= .vsave { registers }
   10014             : bool ARMAsmParser::parseDirectiveRegSave(SMLoc L, bool IsVector) {
   10015          28 :   // Check the ordering of unwind directives
   10016           0 :   if (!UC.hasFnStart())
   10017           0 :     return Error(L, ".fnstart must precede .save or .vsave directives");
   10018          28 :   if (UC.hasHandlerData())
   10019             :     return Error(L, ".save or .vsave must precede .handlerdata directive");
   10020             : 
   10021          28 :   // RAII object to make sure parsed operands are deleted.
   10022          28 :   SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
   10023          28 : 
   10024           0 :   // Parse the register list
   10025          28 :   if (parseRegisterList(Operands) ||
   10026             :       parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
   10027           0 :     return true;
   10028             :   ARMOperand &Op = (ARMOperand &)*Operands[0];
   10029          28 :   if (!IsVector && !Op.isRegList())
   10030             :     return Error(L, ".save expects GPR registers");
   10031             :   if (IsVector && !Op.isDPRRegList())
   10032             :     return Error(L, ".vsave expects DPR registers");
   10033          26 : 
   10034          26 :   getTargetStreamer().emitRegSave(Op.getRegList(), IsVector);
   10035             :   return false;
   10036             : }
   10037             : 
   10038             : /// parseDirectiveInst
   10039             : ///  ::= .inst opcode [, ...]
   10040          64 : ///  ::= .inst.n opcode [, ...]
   10041             : ///  ::= .inst.w opcode [, ...]
   10042          64 : bool ARMAsmParser::parseDirectiveInst(SMLoc Loc, char Suffix) {
   10043           2 :   int Width = 4;
   10044          62 : 
   10045           2 :   if (isThumb()) {
   10046             :     switch (Suffix) {
   10047             :     case 'n':
   10048          60 :       Width = 2;
   10049             :       break;
   10050             :     case 'w':
   10051         120 :       break;
   10052          56 :     default:
   10053           4 :       Width = 0;
   10054             :       break;
   10055          56 :     }
   10056           0 :   } else {
   10057          56 :     if (Suffix)
   10058           0 :       return Error(Loc, "width suffixes are invalid in ARM mode");
   10059             :   }
   10060          56 : 
   10061          56 :   auto parseOne = [&]() -> bool {
   10062             :     const MCExpr *Expr;
   10063             :     if (getParser().parseExpression(Expr))
   10064             :       return true;
   10065             :     const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
   10066             :     if (!Value) {
   10067             :       return Error(Loc, "expected constant expression");
   10068          44 :     }
   10069          44 : 
   10070             :     char CurSuffix = Suffix;
   10071          44 :     switch (Width) {
   10072          32 :     case 2:
   10073          13 :       if (Value->getValue() > 0xffff)
   10074          13 :         return Error(Loc, "inst.n operand is too big, use inst.w instead");
   10075          13 :       break;
   10076             :     case 4:
   10077             :       if (Value->getValue() > 0xffffffff)
   10078           3 :         return Error(Loc, StringRef(Suffix ? "inst.w" : "inst") +
   10079           3 :                               " operand is too big");
   10080           3 :       break;
   10081             :     case 0:
   10082             :       // Thumb mode, no width indicated. Guess from the opcode, if possible.
   10083          12 :       if (Value->getValue() < 0xe800)
   10084           2 :         CurSuffix = 'n';
   10085             :       else if (Value->getValue() >= 0xe8000000)
   10086             :         CurSuffix = 'w';
   10087             :       else
   10088             :         return Error(Loc, "cannot determine Thumb instruction size, "
   10089             :                           "use inst.n/inst.w instead");
   10090             :       break;
   10091             :     default:
   10092             :       llvm_unreachable("only supported widths are 2 and 4");
   10093             :     }
   10094             : 
   10095             :     getTargetStreamer().emitInst(Value->getValue(), CurSuffix);
   10096             :     return false;
   10097             :   };
   10098             : 
   10099             :   if (parseOptionalToken(AsmToken::EndOfStatement))
   10100             :     return Error(Loc, "expected expression following directive");
   10101             :   if (parseMany(parseOne))
   10102             :     return true;
   10103             :   return false;
   10104             : }
   10105             : 
   10106             : /// parseDirectiveLtorg
   10107             : ///  ::= .ltorg | .pool
   10108             : bool ARMAsmParser::parseDirectiveLtorg(SMLoc L) {
   10109             :   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
   10110             :     return true;
   10111             :   getTargetStreamer().emitCurrentConstantPool();
   10112             :   return false;
   10113             : }
   10114             : 
   10115             : bool ARMAsmParser::parseDirectiveEven(SMLoc L) {
   10116             :   const MCSection *Section = getStreamer().getCurrentSectionOnly();
   10117             : 
   10118             :   if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
   10119             :     return true;
   10120             : 
   10121             :   if (!Section) {
   10122             :     getStreamer().InitSections(false);
   10123          42 :     Section = getStreamer().getCurrentSectionOnly();
   10124             :   }
   10125          42 : 
   10126           0 :   assert(Section && "must have section to emit alignment");
   10127          42 :   if (Section->UseCodeAlign())
   10128          11 :     getStreamer().EmitCodeAlignment(2);
   10129             :   else
   10130             :     getStreamer().EmitValueToAlignment(2);
   10131             : 
   10132             :   return false;
   10133             : }
   10134           0 : 
   10135           0 : /// parseDirectivePersonalityIndex
   10136           0 : ///   ::= .personalityindex index
   10137           0 : bool ARMAsmParser::parseDirectivePersonalityIndex(SMLoc L) {
   10138           0 :   MCAsmParser &Parser = getParser();
   10139             :   bool HasExistingPersonality = UC.hasPersonality();
   10140             : 
   10141           0 :   const MCExpr *IndexExpression;
   10142             :   SMLoc IndexLoc = Parser.getTok().getLoc();
   10143             :   if (Parser.parseExpression(IndexExpression) ||
   10144           0 :       parseToken(AsmToken::EndOfStatement,
   10145           0 :                  "unexpected token in '.personalityindex' directive")) {
   10146             :     return true;
   10147           0 :   }
   10148           0 : 
   10149             :   UC.recordPersonalityIndex(L);
   10150             : 
   10151             :   if (!UC.hasFnStart()) {
   10152             :     return Error(L, ".fnstart must precede .personalityindex directive");
   10153           0 :   }
   10154           0 :   if (UC.cantUnwind()) {
   10155             :     Error(L, ".personalityindex cannot be used with .cantunwind");
   10156           0 :     UC.emitCantUnwindLocNotes();
   10157             :     return true;
   10158             :   }
   10159             :   if (UC.hasHandlerData()) {
   10160             :     Error(L, ".personalityindex must precede .handlerdata directive");
   10161             :     UC.emitHandlerDataLocNotes();
   10162             :     return true;
   10163          19 :   }
   10164          19 :   if (HasExistingPersonality) {
   10165             :     Error(L, "multiple personality directives");
   10166             :     UC.emitPersonalityLocNotes();
   10167             :     return true;
   10168          19 :   }
   10169          37 : 
   10170          16 :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(IndexExpression);
   10171             :   if (!CE)
   10172           3 :     return Error(IndexLoc, "index must be a constant number");
   10173             :   if (CE->getValue() < 0 || CE->getValue() >= ARM::EHABI::NUM_PERSONALITY_INDEX)
   10174             :     return Error(IndexLoc,
   10175          16 :                  "personality routine index should be in range [0-3]");
   10176             : 
   10177          16 :   getTargetStreamer().emitPersonalityIndex(CE->getValue());
   10178           1 :   return false;
   10179             : }
   10180          15 : 
   10181           1 : /// parseDirectiveUnwindRaw
   10182           1 : ///   ::= .unwind_raw offset, opcode [, opcode...]
   10183           1 : bool ARMAsmParser::parseDirectiveUnwindRaw(SMLoc L) {
   10184             :   MCAsmParser &Parser = getParser();
   10185          14 :   int64_t StackOffset;
   10186           1 :   const MCExpr *OffsetExpr;
   10187           1 :   SMLoc OffsetLoc = getLexer().getLoc();
   10188           1 : 
   10189             :   if (!UC.hasFnStart())
   10190          13 :     return Error(L, ".fnstart must precede .unwind_raw directives");
   10191           2 :   if (getParser().parseExpression(OffsetExpr))
   10192           2 :     return Error(OffsetLoc, "expected expression");
   10193           2 : 
   10194             :   const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
   10195             :   if (!CE)
   10196          11 :     return Error(OffsetLoc, "offset must be a constant");
   10197             : 
   10198           1 :   StackOffset = CE->getValue();
   10199          10 : 
   10200           1 :   if (Parser.parseToken(AsmToken::Comma, "expected comma"))
   10201             :     return true;
   10202             : 
   10203           9 :   SmallVector<uint8_t, 16> Opcodes;
   10204           9 : 
   10205             :   auto parseOne = [&]() -> bool {
   10206             :     const MCExpr *OE;
   10207             :     SMLoc OpcodeLoc = getLexer().getLoc();
   10208             :     if (check(getLexer().is(AsmToken::EndOfStatement) ||
   10209          64 :                   Parser.parseExpression(OE),
   10210          64 :               OpcodeLoc, "expected opcode expression"))
   10211             :       return true;
   10212             :     const MCConstantExpr *OC = dyn_cast<MCConstantExpr>(OE);
   10213          64 :     if (!OC)
   10214             :       return Error(OpcodeLoc, "opcode value must be a constant");
   10215          64 :     const int64_t Opcode = OC->getValue();
   10216           1 :     if (Opcode & ~0xff)
   10217          63 :       return Error(OpcodeLoc, "invalid opcode");
   10218           1 :     Opcodes.push_back(uint8_t(Opcode));
   10219             :     return false;
   10220          62 :   };
   10221             : 
   10222           1 :   // Must have at least 1 element
   10223             :   SMLoc OpcodeLoc = getLexer().getLoc();
   10224          61 :   if (parseOptionalToken(AsmToken::EndOfStatement))
   10225             :     return Error(OpcodeLoc, "expected opcode expression");
   10226          61 :   if (parseMany(parseOne))
   10227             :     return true;
   10228             : 
   10229             :   getTargetStreamer().emitUnwindRaw(StackOffset, Opcodes);
   10230             :   return false;
   10231             : }
   10232             : 
   10233             : /// parseDirectiveTLSDescSeq
   10234             : ///   ::= .tlsdescseq tls-variable
   10235             : bool ARMAsmParser::parseDirectiveTLSDescSeq(SMLoc L) {
   10236             :   MCAsmParser &Parser = getParser();
   10237             : 
   10238             :   if (getLexer().isNot(AsmToken::Identifier))
   10239             :     return TokError("expected variable after '.tlsdescseq' directive");
   10240             : 
   10241             :   const MCSymbolRefExpr *SRE =
   10242             :     MCSymbolRefExpr::create(Parser.getTok().getIdentifier(),
   10243             :                             MCSymbolRefExpr::VK_ARM_TLSDESCSEQ, getContext());
   10244             :   Lex();
   10245             : 
   10246          60 :   if (parseToken(AsmToken::EndOfStatement,
   10247             :                  "unexpected token in '.tlsdescseq' directive"))
   10248             :     return true;
   10249          60 : 
   10250          60 :   getTargetStreamer().AnnotateTLSDescriptorSequence(SRE);
   10251           1 :   return false;
   10252          59 : }
   10253             : 
   10254             : /// parseDirectiveMovSP
   10255          55 : ///  ::= .movsp reg [, #offset]
   10256          55 : bool ARMAsmParser::parseDirectiveMovSP(SMLoc L) {
   10257             :   MCAsmParser &Parser = getParser();
   10258             :   if (!UC.hasFnStart())
   10259             :     return Error(L, ".fnstart must precede .movsp directives");
   10260             :   if (UC.getFPReg() != ARM::SP)
   10261           0 :     return Error(L, "unexpected .movsp directive");
   10262           0 : 
   10263             :   SMLoc SPRegLoc = Parser.getTok().getLoc();
   10264           0 :   int SPReg = tryParseRegister();
   10265           0 :   if (SPReg == -1)
   10266             :     return Error(SPRegLoc, "register expected");
   10267             :   if (SPReg == ARM::SP || SPReg == ARM::PC)
   10268           0 :     return Error(SPRegLoc, "sp and pc are not permitted in .movsp directive");
   10269             : 
   10270             :   int64_t Offset = 0;
   10271             :   if (Parser.parseOptionalToken(AsmToken::Comma)) {
   10272           0 :     if (Parser.parseToken(AsmToken::Hash, "expected #constant"))
   10273             :       return true;
   10274           0 : 
   10275             :     const MCExpr *OffsetExpr;
   10276           0 :     SMLoc OffsetLoc = Parser.getTok().getLoc();
   10277           0 : 
   10278             :     if (Parser.parseExpression(OffsetExpr))
   10279             :       return Error(OffsetLoc, "malformed offset expression");
   10280             : 
   10281             :     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(OffsetExpr);
   10282          13 :     if (!CE)
   10283          13 :       return Error(OffsetLoc, "offset must be an immediate constant");
   10284          13 : 
   10285           1 :     Offset = CE->getValue();
   10286          12 :   }
   10287           1 : 
   10288             :   if (parseToken(AsmToken::EndOfStatement,
   10289          11 :                  "unexpected token in '.movsp' directive"))
   10290          11 :     return true;
   10291          11 : 
   10292           1 :   getTargetStreamer().emitMovSP(SPReg, Offset);
   10293          10 :   UC.saveFPReg(SPReg);
   10294           2 : 
   10295             :   return false;
   10296             : }
   10297           8 : 
   10298           2 : /// parseDirectiveObjectArch
   10299           2 : ///   ::= .object_arch name
   10300             : bool ARMAsmParser::parseDirectiveObjectArch(SMLoc L) {
   10301             :   MCAsmParser &Parser = getParser();
   10302           1 :   if (getLexer().isNot(AsmToken::Identifier))
   10303             :     return Error(getLexer().getLoc(), "unexpected token");
   10304           1 : 
   10305           0 :   StringRef Arch = Parser.getTok().getString();
   10306             :   SMLoc ArchLoc = Parser.getTok().getLoc();
   10307           1 :   Lex();
   10308             : 
   10309           1 :   ARM::ArchKind ID = ARM::parseArch(Arch);
   10310             : 
   10311           0 :   if (ID == ARM::ArchKind::INVALID)
   10312             :     return Error(ArchLoc, "unknown architecture '" + Arch + "'");
   10313             :   if (parseToken(AsmToken::EndOfStatement))
   10314           6 :     return true;
   10315             : 
   10316             :   getTargetStreamer().emitObjectArch(ID);
   10317             :   return false;
   10318           4 : }
   10319             : 
   10320             : /// parseDirectiveAlign
   10321           4 : ///   ::= .align
   10322             : bool ARMAsmParser::parseDirectiveAlign(SMLoc L) {
   10323             :   // NOTE: if this is not the end of the statement, fall back to the target
   10324             :   // agnostic handling for this directive which will correctly handle this.
   10325             :   if (parseOptionalToken(AsmToken::EndOfStatement)) {
   10326           0 :     // '.align' is target specifically handled to mean 2**2 byte alignment.
   10327           0 :     const MCSection *Section = getStreamer().getCurrentSectionOnly();
   10328           0 :     assert(Section && "must have section to emit alignment");
   10329           0 :     if (Section->UseCodeAlign())
   10330             :       getStreamer().EmitCodeAlignment(4, 0);
   10331           0 :     else
   10332           0 :       getStreamer().EmitValueToAlignment(4, 0, 1, 0);
   10333             :     return false;
   10334             :   }
   10335           0 :   return true;
   10336             : }
   10337           0 : 
   10338           0 : /// parseDirectiveThumbSet
   10339           0 : ///  ::= .thumb_set name, value
   10340           0 : bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
   10341             :   MCAsmParser &Parser = getParser();
   10342           0 : 
   10343           0 :   StringRef Name;
   10344             :   if (check(Parser.parseIdentifier(Name),
   10345             :             "expected identifier after '.thumb_set'") ||
   10346             :       parseToken(AsmToken::Comma, "expected comma after name '" + Name + "'"))
   10347             :     return true;
   10348           0 : 
   10349             :   MCSymbol *Sym;
   10350             :   const MCExpr *Value;
   10351           0 :   if (MCParserUtils::parseAssignmentExpression(Name, /* allow_redef */ true,
   10352             :                                                Parser, Sym, Value))
   10353             :     return true;
   10354             : 
   10355           0 :   getTargetStreamer().emitThumbSet(Sym, Value);
   10356           0 :   return false;
   10357             : }
   10358           0 : 
   10359           0 : /// Force static initialization.
   10360             : extern "C" void LLVMInitializeARMAsmParser() {
   10361             :   RegisterMCAsmParser<ARMAsmParser> X(getTheARMLETarget());
   10362             :   RegisterMCAsmParser<ARMAsmParser> Y(getTheARMBETarget());
   10363             :   RegisterMCAsmParser<ARMAsmParser> A(getTheThumbLETarget());
   10364             :   RegisterMCAsmParser<ARMAsmParser> B(getTheThumbBETarget());
   10365             : }
   10366           0 : 
   10367           0 : #define GET_REGISTER_MATCHER
   10368             : #define GET_SUBTARGET_FEATURE_NAME
   10369           0 : #define GET_MATCHER_IMPLEMENTATION
   10370           0 : #define GET_MNEMONIC_SPELL_CHECKER
   10371           0 : #include "ARMGenAsmMatcher.inc"
   10372           0 : 
   10373           0 : // Some diagnostics need to vary with subtarget features, so they are handled
   10374             : // here. For example, the DPR class has either 16 or 32 registers, depending
   10375             : // on the FPU available.
   10376             : const char *
   10377           0 : ARMAsmParser::getCustomOperandDiag(ARMMatchResultTy MatchError) {
   10378             :   switch (MatchError) {
   10379           0 :   // rGPR contains sp starting with ARMv8.
   10380             :   case Match_rGPR:
   10381           0 :     return hasV8Ops() ? "operand must be a register in range [r0, r14]"
   10382           0 :                       : "operand must be a register in range [r0, r12] or r14";
   10383             :   // DPR contains 16 registers for some FPUs, and 32 for others.
   10384             :   case Match_DPR:
   10385             :     return hasD16() ? "operand must be a register in range [d0, d15]"
   10386       75416 :                     : "operand must be a register in range [d0, d31]";
   10387       75416 :   case Match_DPR_RegList:
   10388       75416 :     return hasD16() ? "operand must be a list of registers in range [d0, d15]"
   10389       75416 :                     : "operand must be a list of registers in range [d0, d31]";
   10390       75416 : 
   10391       75416 :   // For all other diags, use the static string from tablegen.
   10392             :   default:
   10393             :     return getMatchKindDiag(MatchError);
   10394             :   }
   10395             : }
   10396             : 
   10397             : // Process the list of near-misses, throwing away ones we don't want to report
   10398             : // to the user, and converting the rest to a source location and string that
   10399             : // should be reported.
   10400             : void
   10401             : ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
   10402             :                                SmallVectorImpl<NearMissMessage> &NearMissesOut,
   10403        4935 :                                SMLoc IDLoc, OperandVector &Operands) {
   10404        4935 :   // TODO: If operand didn't match, sub in a dummy one and run target
   10405             :   // predicate, so that we can avoid reporting near-misses that are invalid?
   10406             :   // TODO: Many operand types dont have SuperClasses set, so we report
   10407          78 :   // redundant ones.
   10408             :   // TODO: Some operands are superclasses of registers (e.g.
   10409             :   // MCK_RegShiftedImm), we don't have any way to represent that currently.
   10410             :   // TODO: This is not all ARM-specific, can some of it be factored out?
   10411             : 
   10412          20 :   // Record some information about near-misses that we have already seen, so
   10413             :   // that we can avoid reporting redundant ones. For example, if there are
   10414             :   // variants of an instruction that take 8- and 16-bit immediates, we want
   10415          16 :   // to only report the widest one.
   10416             :   std::multimap<unsigned, unsigned> OperandMissesSeen;
   10417             :   SmallSet<uint64_t, 4> FeatureMissesSeen;
   10418        4821 :   bool ReportedTooFewOperands = false;
   10419        4821 : 
   10420             :   // Process the near-misses in reverse order, so that we see more general ones
   10421             :   // first, and so can avoid emitting more specific ones.
   10422             :   for (NearMissInfo &I : reverse(NearMissesIn)) {
   10423             :     switch (I.getKind()) {
   10424             :     case NearMissInfo::NearMissOperand: {
   10425             :       SMLoc OperandLoc =
   10426             :           ((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
   10427        4299 :       const char *OperandDiag =
   10428             :           getCustomOperandDiag((ARMMatchResultTy)I.getOperandError());
   10429             : 
   10430             :       // If we have already emitted a message for a superclass, don't also report
   10431             :       // the sub-class. We consider all operand classes that we don't have a
   10432             :       // specialised diagnostic for to be equal for the propose of this check,
   10433             :       // so that we don't report the generic error multiple times on the same
   10434             :       // operand.
   10435             :       unsigned DupCheckMatchClass = OperandDiag ? I.getOperandClass() : ~0U;
   10436             :       auto PrevReports = OperandMissesSeen.equal_range(I.getOperandIndex());
   10437             :       if (std::any_of(PrevReports.first, PrevReports.second,
   10438             :                       [DupCheckMatchClass](
   10439             :                           const std::pair<unsigned, unsigned> Pair) {
   10440             :             if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
   10441             :               return Pair.second == DupCheckMatchClass;
   10442             :             else
   10443        4299 :               return isSubclass((MatchClassKind)DupCheckMatchClass,
   10444             :                                 (MatchClassKind)Pair.second);
   10445             :           }))
   10446             :         break;
   10447             :       OperandMissesSeen.insert(
   10448       11951 :           std::make_pair(I.getOperandIndex(), DupCheckMatchClass));
   10449        7652 : 
   10450        4935 :       NearMissMessage Message;
   10451             :       Message.Loc = OperandLoc;
   10452        4935 :       if (OperandDiag) {
   10453             :         Message.Message = OperandDiag;
   10454        4935 :       } else if (I.getOperandClass() == InvalidMatchClass) {
   10455             :         Message.Message = "too many operands for instruction";
   10456             :       } else {
   10457             :         Message.Message = "invalid operand for instruction";
   10458             :         LLVM_DEBUG(
   10459             :             dbgs() << "Missing diagnostic string for operand class "
   10460             :                    << getMatchClassName((MatchClassKind)I.getOperandClass())
   10461        4935 :                    << I.getOperandClass() << ", error " << I.getOperandError()
   10462        4935 :                    << ", opcode " << MII.getName(I.getOpcode()) << "\n");
   10463        4935 :       }
   10464             :       NearMissesOut.emplace_back(Message);
   10465             :       break;
   10466           0 :     }
   10467           0 :     case NearMissInfo::NearMissFeature: {
   10468             :       uint64_t MissingFeatures = I.getFeatures();
   10469           0 :       // Don't report the same set of features twice.
   10470             :       if (FeatureMissesSeen.count(MissingFeatures))
   10471             :         break;
   10472             :       FeatureMissesSeen.insert(MissingFeatures);
   10473             : 
   10474        3403 :       // Special case: don't report a feature set which includes arm-mode for
   10475             :       // targets that don't have ARM mode.
   10476             :       if ((MissingFeatures & Feature_IsARM) && !hasARM())
   10477        3403 :         break;
   10478        3403 :       // Don't report any near-misses that both require switching instruction
   10479             :       // set, and adding other subtarget features.
   10480        1487 :       if (isThumb() && (MissingFeatures & Feature_IsARM) &&
   10481             :           (MissingFeatures & ~Feature_IsARM))
   10482             :         break;
   10483             :       if (!isThumb() && (MissingFeatures & Feature_IsThumb) &&
   10484             :           (MissingFeatures & ~Feature_IsThumb))
   10485             :         break;
   10486             :       if (!isThumb() && (MissingFeatures & Feature_IsThumb2) &&
   10487             :           (MissingFeatures & ~(Feature_IsThumb2 | Feature_IsThumb)))
   10488             :         break;
   10489             :       if (isMClass() && (MissingFeatures & Feature_HasNEON))
   10490        3403 :         break;
   10491             : 
   10492             :       NearMissMessage Message;
   10493        2407 :       Message.Loc = IDLoc;
   10494        2407 :       raw_svector_ostream OS(Message.Message);
   10495             : 
   10496        2407 :       OS << "instruction requires:";
   10497             :       uint64_t Mask = 1;
   10498        2392 :       for (unsigned MaskPos = 0; MaskPos < (sizeof(MissingFeatures) * 8 - 1);
   10499             :            ++MaskPos) {
   10500             :         if (MissingFeatures & Mask) {
   10501             :           OS << " " << getSubtargetFeatureName(MissingFeatures & Mask);
   10502        2610 :         }
   10503             :         Mask <<= 1;
   10504             :       }
   10505             :       NearMissesOut.emplace_back(Message);
   10506        2355 : 
   10507         181 :       break;
   10508             :     }
   10509        2270 :     case NearMissInfo::NearMissPredicate: {
   10510          35 :       NearMissMessage Message;
   10511             :       Message.Loc = IDLoc;
   10512        2240 :       switch (I.getPredicateError()) {
   10513          50 :       case Match_RequiresNotITBlock:
   10514             :         Message.Message = "flag setting instruction only valid outside IT block";
   10515        2196 :         break;
   10516             :       case Match_RequiresITBlock:
   10517             :         Message.Message = "instruction only valid inside IT block";
   10518             :         break;
   10519        2194 :       case Match_RequiresV6:
   10520             :         Message.Message = "instruction variant requires ARMv6 or later";
   10521             :         break;
   10522        2194 :       case Match_RequiresThumb2:
   10523             :         Message.Message = "instruction variant requires Thumb2";
   10524      140416 :         break;
   10525             :       case Match_RequiresV8:
   10526      138222 :         Message.Message = "instruction variant requires ARMv8 or later";
   10527        2332 :         break;
   10528             :       case Match_RequiresFlagSetting:
   10529      138222 :         Message.Message = "no flag-preserving variant of this instruction available";
   10530             :         break;
   10531        2194 :       case Match_InvalidOperand:
   10532             :         Message.Message = "invalid operand for instruction";
   10533             :         break;
   10534             :       default:
   10535             :         llvm_unreachable("Unhandled target predicate error");
   10536             :         break;
   10537          33 :       }
   10538          33 :       NearMissesOut.emplace_back(Message);
   10539             :       break;
   10540             :     }
   10541           0 :     case NearMissInfo::NearMissTooFewOperands: {
   10542             :       if (!ReportedTooFewOperands) {
   10543             :         SMLoc EndLoc = ((ARMOperand &)*Operands.back()).getEndLoc();
   10544           0 :         NearMissesOut.emplace_back(NearMissMessage{
   10545             :             EndLoc, StringRef("too few operands for instruction")});
   10546             :         ReportedTooFewOperands = true;
   10547           1 :       }
   10548             :       break;
   10549             :     }
   10550           2 :     case NearMissInfo::NoNearMiss:
   10551             :       // This should never leave the matcher.
   10552             :       llvm_unreachable("not a near-miss");
   10553          14 :       break;
   10554             :     }
   10555             :   }
   10556           2 : }
   10557             : 
   10558             : void ARMAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
   10559          14 :                                     SMLoc IDLoc, OperandVector &Operands) {
   10560           0 :   SmallVector<NearMissMessage, 4> Messages;
   10561           0 :   FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
   10562             : 
   10563             :   if (Messages.size() == 0) {
   10564          33 :     // No near-misses were found, so the best we can do is "invalid
   10565             :     // instruction".
   10566             :     Error(IDLoc, "invalid instruction");
   10567         277 :   } else if (Messages.size() == 1) {
   10568         277 :     // One near miss was found, report it as the sole error.
   10569             :     Error(Messages[0].Loc, Messages[0].Message);
   10570         122 :   } else {
   10571             :     // More than one near miss, so report a generic "invalid instruction"
   10572             :     // error, followed by notes for each of the near-misses.
   10573             :     Error(IDLoc, "invalid instruction, any one of the following would fix this:");
   10574             :     for (auto &M : Messages) {
   10575             :       Note(M.Loc, M.Message);
   10576             :     }
   10577             :   }
   10578             : }
   10579             : 
   10580             : // FIXME: This structure should be moved inside ARMTargetParser
   10581             : // when we start to table-generate them, and we can use the ARM
   10582        4299 : // flags below, that were generated by table-gen.
   10583             : static const struct {
   10584        4299 :   const unsigned Kind;
   10585             :   const uint64_t ArchCheck;
   10586        4299 :   const FeatureBitset Features;
   10587        4299 : } Extensions[] = {
   10588             :   { ARM::AEK_CRC, Feature_HasV8, {ARM::FeatureCRC} },
   10589        8598 :   { ARM::AEK_CRYPTO,  Feature_HasV8,
   10590             :     {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
   10591             :   { ARM::AEK_FP, Feature_HasV8, {ARM::FeatureFPARMv8} },
   10592         198 :   { (ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM), Feature_HasV7 | Feature_IsNotMClass,
   10593        4101 :     {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
   10594             :   { ARM::AEK_MP, Feature_HasV7 | Feature_IsNotMClass, {ARM::FeatureMP} },
   10595        2720 :   { ARM::AEK_SIMD, Feature_HasV8, {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
   10596             :   { ARM::AEK_SEC, Feature_HasV6K, {ARM::FeatureTrustZone} },
   10597             :   // FIXME: Only available in A-class, isel not predicated
   10598             :   { ARM::AEK_VIRT, Feature_HasV7, {ARM::FeatureVirtualization} },
   10599        1381 :   { ARM::AEK_FP16, Feature_HasV8_2a, {ARM::FeatureFPARMv8, ARM::FeatureFullFP16} },
   10600        4352 :   { ARM::AEK_RAS, Feature_HasV8, {ARM::FeatureRAS} },
   10601        2971 :   // FIXME: Unsupported extensions.
   10602             :   { ARM::AEK_OS, Feature_None, {} },
   10603             :   { ARM::AEK_IWMMXT, Feature_None, {} },
   10604        4299 :   { ARM::AEK_IWMMXT2, Feature_None, {} },
   10605             :   { ARM::AEK_MAVERICK, Feature_None, {} },
   10606             :   { ARM::AEK_XSCALE, Feature_None, {} },
   10607             : };
   10608             : 
   10609             : /// parseDirectiveArchExtension
   10610             : ///   ::= .arch_extension [no]feature
   10611             : bool ARMAsmParser::parseDirectiveArchExtension(SMLoc L) {
   10612             :   MCAsmParser &Parser = getParser();
   10613             : 
   10614             :   if (getLexer().isNot(AsmToken::Identifier))
   10615             :     return Error(getLexer().getLoc(), "expected architecture extension name");
   10616             : 
   10617             :   StringRef Name = Parser.getTok().getString();
   10618             :   SMLoc ExtLoc = Parser.getTok().getLoc();
   10619             :   Lex();
   10620             : 
   10621             :   if (parseToken(AsmToken::EndOfStatement,
   10622             :                  "unexpected token in '.arch_extension' directive"))
   10623             :     return true;
   10624             : 
   10625             :   bool EnableFeature = true;
   10626             :   if (Name.startswith_lower("no")) {
   10627             :     EnableFeature = false;
   10628             :     Name = Name.substr(2);
   10629             :   }
   10630             :   unsigned FeatureKind = ARM::parseArchExt(Name);
   10631             :   if (FeatureKind == ARM::AEK_INVALID)
   10632             :     return Error(ExtLoc, "unknown architectural extension: " + Name);
   10633             : 
   10634             :   for (const auto &Extension : Extensions) {
   10635             :     if (Extension.Kind != FeatureKind)
   10636             :       continue;
   10637           0 : 
   10638           0 :     if (Extension.Features.none())
   10639             :       return Error(ExtLoc, "unsupported architectural extension: " + Name);
   10640           0 : 
   10641           0 :     if ((getAvailableFeatures() & Extension.ArchCheck) != Extension.ArchCheck)
   10642             :       return Error(ExtLoc, "architectural extension '" + Name +
   10643           0 :                                "' is not "
   10644           0 :                                "allowed for the current base architecture");
   10645             : 
   10646             :     MCSubtargetInfo &STI = copySTI();
   10647           0 :     FeatureBitset ToggleFeatures = EnableFeature
   10648             :       ? (~STI.getFeatureBits() & Extension.Features)
   10649           0 :       : ( STI.getFeatureBits() & Extension.Features);
   10650             : 
   10651             :     uint64_t Features =
   10652           0 :         ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
   10653             :     setAvailableFeatures(Features);
   10654           0 :     return false;
   10655             :   }
   10656           0 : 
   10657           0 :   return Error(ExtLoc, "unknown architectural extension: " + Name);
   10658           0 : }
   10659             : 
   10660           0 : // Define this matcher function after the auto-generated include so we
   10661           0 : // have the match class enum definitions.
   10662           0 : unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   10663             :                                                   unsigned Kind) {
   10664           0 :   ARMOperand &Op = static_cast<ARMOperand &>(AsmOp);
   10665           0 :   // If the kind is a token for a literal immediate, check if our asm
   10666             :   // operand matches. This is for InstAliases which have a fixed-value
   10667           0 :   // immediate in the syntax.
   10668           0 :   switch (Kind) {
   10669             :   default: break;
   10670           0 :   case MCK__35_0:
   10671             :     if (Op.isImm())
   10672           0 :       if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm()))
   10673             :         if (CE->getValue() == 0)
   10674           0 :           return Match_Success;
   10675             :     break;
   10676             :   case MCK_ModImm:
   10677             :     if (Op.isImm()) {
   10678           0 :       const MCExpr *SOExpr = Op.getImm();
   10679             :       int64_t Value;
   10680           0 :       if (!SOExpr->evaluateAsAbsolute(Value))
   10681             :         return Match_Success;
   10682             :       assert((Value >= std::numeric_limits<int32_t>::min() &&
   10683           0 :               Value <= std::numeric_limits<uint32_t>::max()) &&
   10684             :              "expression value must be representable in 32 bits");
   10685             :     }
   10686             :     break;
   10687             :   case MCK_rGPR:
   10688      556772 :     if (hasV8Ops() && Op.isReg() && Op.getReg() == ARM::SP)
   10689             :       return Match_Success;
   10690             :     return Match_rGPR;
   10691             :   case MCK_GPRPair:
   10692             :     if (Op.isReg() &&
   10693             :         MRI->getRegClass(ARM::GPRRegClassID).contains(Op.getReg()))
   10694      556772 :       return Match_Success;
   10695             :     break;
   10696        2341 :   }
   10697        2341 :   return Match_InvalidOperand;
   10698         576 : }

Generated by: LCOV version 1.13