ARMAsmParser.cpp revision 42e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h"
2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h"
3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbachenum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
4398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
4494b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
48a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Map of register aliases registers via the .req directive.
49a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StringMap<unsigned> RegisterReqs;
50a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
68f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
69f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
70f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
76a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
77a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
78a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
79f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
80f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
84ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
85ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
86ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
890d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
989a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
102a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveReq(StringRef Name, SMLoc L);
103a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveUnreq(SMLoc L);
104d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveArch(SMLoc L);
105d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveEabiAttr(SMLoc L);
106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
10989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
111fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
113ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
115ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
116ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
117ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
118ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
119ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
12047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
12147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
123194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
124194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
125194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
126acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
127acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
128acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
12932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
130ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
131ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
133acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
134acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
135acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1400692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1410692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
14643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
147f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
149f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1538bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1558bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1578bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
166c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
167580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
169293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
171251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1729d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
173862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1747636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
175ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
180a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
181eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
182eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
183ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
184ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
186ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1879ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
189548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
190548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
192ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
2042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
20614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
207623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
208623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
21088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
21112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
21212431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
21312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
21412431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
2154334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2164334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
2174334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2184334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
220189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
223f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
224d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
225d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
226189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
22847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
229194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
230f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
231194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
232194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
23347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
235ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
23694b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
23832869205052430f45d598fba25ab878d8b29da2dEvan Cheng
239ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
240ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
242f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
244ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
245ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
249189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
25247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
25347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
25816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
25916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2603a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
262a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
264146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
278460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
283862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
28498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
28621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
28721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
28821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
28921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
29121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
29524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
3008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
305fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
306fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
31189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
31389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
31589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
31689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
335862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
336862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
337862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
338862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3400aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
341862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
342862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3438155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
344460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
345460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
346460a90540b045c102012da2492999557e6840526Jim Grosbach
347460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
348cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
349cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
35016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3516a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
352a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
353a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
35957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
36057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
361eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
363e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
367f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
368f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
369f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
373580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
374e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
375580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
378e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
379e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
381af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
38292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
38392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
38492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
38592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
386af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
391293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
392293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
393293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
394a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
39516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
396146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
397146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
399762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
400762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
40789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
40889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
414762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
41821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
41924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
421862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
42298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
424862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
425862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
42721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
428fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
429fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4319b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4329b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
43321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
434762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
437706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
438706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
440e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
449a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
45721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
458af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
45992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
46321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
464293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
465293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
466460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
467460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
468460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
470762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
47821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
482fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
484fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
485fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
50024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
503cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
50421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    assert(isImm() && "Invalid access!");
505cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
506cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
508460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
509460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
510460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
511460a90540b045c102012da2492999557e6840526Jim Grosbach  }
512460a90540b045c102012da2492999557e6840526Jim Grosbach
513706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
51421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
515706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
516706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
517706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
523584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
525584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
526584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
527584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
52821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
53121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
53221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
53651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  bool isFPImm() const {
53751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!isImm()) return false;
53851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
53951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!CE) return false;
54051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
54151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    return Val != -1;
54251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  }
5434050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits16() const {
5444050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5454050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5464050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5474050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5484050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 0 && Value <= 16;
5494050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
5504050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits32() const {
5514050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5524050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5534050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5544050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5554050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 1 && Value <= 32;
5564050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
557a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
55821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
559a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
560a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
561a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
562a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
563a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
56472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
56521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
56672f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
56772f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
56872f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
56972f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
57072f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
57172f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
57221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57472f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57572f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
57672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
57772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
57921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
5806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
585587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
58621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
587587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
588587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
590587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
591587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
592587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
59321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
594587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
595587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
596587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
597587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
598587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
59983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
60021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
60183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
60721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
61183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
61283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6137c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
61421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6157c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6167c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6187c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6197c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
620730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
62121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
622730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
623730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
624730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
625730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
626730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
62821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
63521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6393b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
64221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6463b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6473b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6486b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
64921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6506b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6516b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6536b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
65621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6606b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
66321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6676b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
67021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6746b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6763b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
67721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6793b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6813b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
68421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6883b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
69121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6953b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
697f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
69821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
699f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
700f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
701f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
703f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7044a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
70521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7064a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7074a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7094a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
711ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
71221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
713ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
714ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
715ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
716ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
717ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
718fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
71921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
720fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
721fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
722fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
723fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
724fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
725ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
72621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
727ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
728ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
729ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
730ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
731ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
732ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
733ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
734ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
73521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
736ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
737ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
738ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
739ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
740ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
74170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
74221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
74370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
74470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
74570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
74670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
74770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
748f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
74921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
750f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
751f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
752f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
753f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
75621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7626bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
76321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7646bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7656bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
7666bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
7676bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
7686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
769e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
77021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
771e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
772e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
773e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
774e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
775e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
7763bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
77721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7783bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7793bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
7803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
7813bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getSOImmVal(-Value) != -1;
7823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
7836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
78421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
7876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
7886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
7896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
79089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
79121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
79289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
79389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
79489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
79589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
79689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
7973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
79821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getT2SOImmVal(-Value) != -1;
8033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
804c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
80521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
806c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
807c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
809c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
81121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
81221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
81321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
81421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
81521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
81621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
81721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
81821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
81921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
82021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
82121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
82221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
82321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
824f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
825430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
826f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
82757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
828f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
83157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
83257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
83357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
8340b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  bool isMemPCRelImm12() const {
8350b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
8360b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8370b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base register must be PC.
8380b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum != ARM::PC)
8390b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8400b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Immediate offset in range [-4095, 4095].
8410b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!Memory.OffsetImm) return true;
8420b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8430b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8440b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
84557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
84657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
847ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
84957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
851e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
853e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
854e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
857039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
85821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
859039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
860039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
861039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
862039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
863039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
864039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
8652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
8662f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
8672f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
8682f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
86921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
8702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
87157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
873e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
8742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
875e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
877e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
878e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
88221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
8832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
88421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
890251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
891251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
894681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
895681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
896681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
89721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
898681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
89957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
901e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
903e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
904e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9050da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
906681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9087f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
909e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9117f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
915e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
91757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
92257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
923ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
924ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
925ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
926ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
92757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
929ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
930ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
931e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
932ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
933e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
934ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
935ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
940e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
94157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
94287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
943e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
944e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
94560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
94660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
947e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
94857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
94960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
95060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
951e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
952e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
953ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
954ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
95538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
956e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
95757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
95838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
95938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
960e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
961e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
96238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
96338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
96448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
965e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
96748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
96848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
969e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
970e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
97148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
97248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
973ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
97457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
976ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
977ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
978e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
979e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
980ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
981505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
982a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
9832f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
9842f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
9852f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
98621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
9872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
98857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
989a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
991e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
992e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
995b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
99657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
997b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
998b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
999e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1000e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1001b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
100457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1005f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10060b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10070b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
10087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1009e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1010e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10114d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1012f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1013f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
101457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1015f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1016f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1017e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1018e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1020f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1021a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
102257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1023a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
10240b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10250b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
1026a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1027df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1028e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1029df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1031a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
103257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1033a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1035e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1036e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1037a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1038a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
104009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
104109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
104209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
104321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
104409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
104509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
104657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1047ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1049e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1050e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10510da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
105421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1056ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
10577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
105863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1059ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
10602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
106121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10632bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
10652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
10672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
10687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
106921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
107021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
10713483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
10730aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
10740aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
10750aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
10760aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
10770aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
10780aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1079862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
10800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1081862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1082862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1084280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  bool isVecListTwoD() const {
10850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1086280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    return VectorList.Count == 2;
1087280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
1088280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
1089cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
10900aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1091cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1092cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1093cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1094b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
10950aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1096b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1097b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1098b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
10994661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  bool isVecListTwoQ() const {
11000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11010aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return VectorList.Count == 2;
11024661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  }
11034661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach
1104c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  bool isVecListThreeQ() const {
1105c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
1106c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return VectorList.Count == 3;
1107c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
1108c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
11097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  bool isVecListFourQ() const {
11107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    return VectorList.Count == 4;
11127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  }
11137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
11143471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isSingleSpacedVectorAllLanes() const {
11153471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
11163471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11173471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isDoubleSpacedVectorAllLanes() const {
11183471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
11193471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
112098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
11213471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
112298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
112398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
112498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
112513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  bool isVecListTwoDAllLanes() const {
11263471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11273471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return VectorList.Count == 2;
11283471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11293471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach
11303471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isVecListTwoQAllLanes() const {
11313471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
113213af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
113313af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
113413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11355e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeDAllLanes() const {
11365e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11375e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11385e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11395e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
11405e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeQAllLanes() const {
11415e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
11425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
1145a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourDAllLanes() const {
1146a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1147a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1148a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1149a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
1150a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourQAllLanes() const {
1151a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
1152a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1153a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1154a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
115595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isSingleSpacedVectorIndexed() const {
115695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
115795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
115895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isDoubleSpacedVectorIndexed() const {
115995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
116095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
11617636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
116295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11637636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
11647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
11657636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1166799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
116795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1168799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1169799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1170799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1171799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
117295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1173799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1174799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1175799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
11769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
117795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
11799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
11809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1181799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
118295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
118395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
118495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
118595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
118695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQWordIndexed() const {
118795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
118895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
118995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
119095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
119195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQHWordIndexed() const {
119295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1193799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1194799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1195799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1196799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
119795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1198799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1199799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1200799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12013a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDByteIndexed() const {
12023a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12033a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
12043a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12053a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12063a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDHWordIndexed() const {
12073a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12083a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12093a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12103a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12113a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQWordIndexed() const {
12123a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12133a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12143a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12153a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12163a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQHWordIndexed() const {
12173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12183a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12193a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12203a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12213a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDWordIndexed() const {
12223a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12233a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12243a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12253a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
1226e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDByteIndexed() const {
1227e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1228e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1229e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1230e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1231e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDHWordIndexed() const {
1232e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1233e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1234e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1235e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1236e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQWordIndexed() const {
1237e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1238e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1239e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1240e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1241e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQHWordIndexed() const {
1242e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1243e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1244e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1245e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1246e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDWordIndexed() const {
1247e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1248e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1249e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1250e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1251460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1252460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1253460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1254460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1255460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1256460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1257460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1258460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1259460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1260460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1261460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1262460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1263460a90540b045c102012da2492999557e6840526Jim Grosbach
12640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
126521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
12680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
12690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
12700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
12710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
12720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
12730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1274460a90540b045c102012da2492999557e6840526Jim Grosbach
1275ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
127621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1277ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1278ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1279ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1280ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1281ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1282ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1283ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1284ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
12856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
128621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
12896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
12906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
12916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
12926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
12936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
12946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
12956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
12966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
12976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
12986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
129921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13139b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  bool isNEONi32vmovNeg() const {
131421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13159b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13169b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // Must be a constant.
13179b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (!CE) return false;
13189b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    int64_t Value = ~CE->getValue();
13199b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13209b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13219b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    return (Value >= 0 && Value < 256) ||
13229b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13239b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13249b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13259b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13269b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13279b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
13286248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1329f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
133021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1331f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1332f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1333f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1334f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1335f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1336f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1337f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1338f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1339f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1340f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
13413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
134214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
134314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
134414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
134514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
13463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
13473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
13483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
13493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
13503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
13518462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1352345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
13538462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
135404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
135504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
13568462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
13578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1358fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1359fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1360fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1361fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1362fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
13639b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
13649b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13659b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
13669b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13679b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
13689b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
13699b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13709b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
13719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
137389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
137489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
137589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
137689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
137789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
137889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
137989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
138089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
138189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
138289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1383d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1384d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1385d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1386d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1387d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1388a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1389a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1390a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1392a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1393af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1394e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1395430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1396430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1397af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1398af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1399e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1400af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1401e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1402e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1403af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1404152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1405430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1406430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1407af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
140892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1409af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
141092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
141192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1412580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
14130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1414580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
14160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
141887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
14197729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
14205fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
14215fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
14227729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
14237729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
142487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
142587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
14260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
14270f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14280f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14290f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14300f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
14310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
14357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
14377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
14387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1440293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1441293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1442293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1443293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1444293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1445293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1446293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1447293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1448293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1449293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1450293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
14513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
14526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
14546b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
14556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
14564050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits16Operands(MCInst &Inst, unsigned N) const {
14574050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14584050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14594050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
14604050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14614050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14624050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits32Operands(MCInst &Inst, unsigned N) const {
14634050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14644050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14654050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
14664050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14674050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14689d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
14699d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
147051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
147151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
147251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14739d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
14749d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1475a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1476a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1477a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1478a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1479a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1480a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1481a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1482a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
148372f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
148472f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
148572f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
148672f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
148772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
148872f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
148972f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
149072f39f8436848885176943b0ba985a7171145423Jim Grosbach
149172f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
149272f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
149372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
149472f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
149572f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
149672f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
149772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
149872f39f8436848885176943b0ba985a7171145423Jim Grosbach
1499f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1500f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1501f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1502f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1503f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1504f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1505f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1506f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
15074a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
15084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15094a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
15104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
15114a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
15134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
15144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
151570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
151670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
151770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
151870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
151970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
152070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
152170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1522ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1523ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1524f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1525f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1526f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1527f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1528f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1529f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1530f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1531f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1532f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
153389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
153489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
153589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
153689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
153789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
153889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
153989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
154089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
15413bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
15423bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15433bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
15443bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15453bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15463bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15473bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15483bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1549e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1550e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1551e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1552e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1553e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1554e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1555e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1556e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
15573bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
15583bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15593bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
15603bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15613bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15623bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15633bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15643bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1565706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1566706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1567706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1568706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1569706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
15707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
15717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1572e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1573505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1574505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
15750b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
15760b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15770b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int32_t Imm = Memory.OffsetImm->getValue();
15780b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // FIXME: Handle #-0
15790b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
15800b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
15810b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
15820b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach
158357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
158457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
158557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
158657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
158757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
158857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
15897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
15907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1591e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1592e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
15937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
15947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
15957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
15967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
15977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
15987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
15997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
16007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1601e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1602e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1604e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1605e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1607ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1608ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1609039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1610039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1611039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1612039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1613039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1614039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1615039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1616039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1617039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1618039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1619039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1620039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1621039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1622039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
16232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
16242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
16252f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
16262f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
16272f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
16282f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
16292f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
16302f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
16312f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
16322f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
16332f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
16342f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1635e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1636e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
16392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
16412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
16422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
16432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
16442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1645e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
16462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1647e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1648e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
16532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
165421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
16552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
16562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
16572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
16582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1659251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
16602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
16612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
16632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
16642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
16652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
16672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
16702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
16712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
16757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1676681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1677681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1678681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1679681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1680681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1681681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1682681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1683681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1684681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
16857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1686e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
16877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
16897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
16917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1692e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
16937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
16957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1696a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1697a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
16982f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
16992f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
17002f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
17012f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
17022f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
17032f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
17042f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17052f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17062f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1707e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1708e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1709a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1710a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1711a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1712b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1713b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1714b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1715e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1716e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1717b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1718b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1719b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
17207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
17217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1722e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1725ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1726ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1727f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1728f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1729f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1730f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1731a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1732f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1733a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1734a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1735a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1736a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1737a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
173821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
1739a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1740a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1741a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1742a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1743a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1744a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1745e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1746e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1747a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1748a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1749a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
17507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
17517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
175209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
175321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
175409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
175509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
175609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
175709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
175809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
175909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1760e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1761e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
176492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
17657f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
17667f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1767e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1768e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17697f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17707f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17717f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
17727f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1773e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1774e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17757f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17767f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
17787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1779430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1780430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1781430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1782e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1783e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1786d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1787ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1788ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1789e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1790e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1791e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1792ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1793ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
17947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
17957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1796e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1797e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
179814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
17993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
180060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
180160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1802e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1803e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
180460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
180548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
180648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
180738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
180838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1809e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
181138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
181238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
181338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
181448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
181548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1816e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1817e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
181848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
181960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
182060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1821ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1822ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1823e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1824e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1825ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1826ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1827ecd858968384be029574d845eb098d357049e02eJim Grosbach
18287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
18297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
18327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
18337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
183463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
18357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
18367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1837f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1838ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
18392bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
18402bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
18412bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18422bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
18432bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
18442bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
18452bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
18462bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
18472bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
18482bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
18492bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
18502bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
18517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
18527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1854f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1855f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1856f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1857f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1858f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1859f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1860f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1861f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1862f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1863f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1864f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1865f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1866ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1867ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1868584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1869584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1870584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1871584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1872584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1874a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1875a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
18786029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1879862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1880862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1881862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1882862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
18837636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
18847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
18867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
18877636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
18887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1889460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1890460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1891460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1892460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1893460a90540b045c102012da2492999557e6840526Jim Grosbach
1894460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1895460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1896460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1897460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1898460a90540b045c102012da2492999557e6840526Jim Grosbach
1899460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1900460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1901460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1902460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1903460a90540b045c102012da2492999557e6840526Jim Grosbach
19040e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
19050e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19060e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19070e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
19080e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19090e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
19100e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
19110e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1912ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1913ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1914ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1915ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1916ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1917ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1918ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1919ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1920ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1921ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1922ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1923ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
19246248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
19256248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19266248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19276248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19286248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
19296248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
19306248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
19316248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
19326248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
19336248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
19346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
19356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
19386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
19396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
19436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
19486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
19499b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19509b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
19519b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach
19529b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
19539b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19549b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19559b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19569b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    unsigned Value = ~CE->getValue();
19579b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19589b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19599b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19609b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19619b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffffff)
19629b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 24) | 0x600;
19636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1966f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1967f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1968f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1969f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1970f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1971f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1972f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1973f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1974f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1975f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1976f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1977f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1978b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1979b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
198089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
198121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
198289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
198389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
198489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
198589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
198689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
198789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
19883a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
198921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1990345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1991345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1992345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
19933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1994345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1995345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1996fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
199721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1998fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1999fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2000fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2001fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2002fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2003fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2004fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
200521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
2006fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2007fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2008fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2009fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2010fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2011fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
20129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
20139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
20149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
20159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
20169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
20179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
20189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
20199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2020d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
202121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
2022d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
2023d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
2024d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
2025d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
2026d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
2027d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
20283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
202921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
2030762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
2031762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
2032762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2033762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
20343a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2035a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2036a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
203750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
203821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
2039762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
2040762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2041762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
20423a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2043a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2044a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2045e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
2046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
2047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
2048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
2049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
205021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
2051af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
2052af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
2053af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
2054af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
2055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
2056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
2057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
2058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
206092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
206192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
206292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
206392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
206421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
2065af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
2066af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
2067af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
206892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
206992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
207092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
207192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
207292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
2073580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
20740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
207521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
2076580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
2077580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
20780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
20790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
20800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
20810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
20820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
20837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
208421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
20857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
20867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
20877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
20887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
20897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2091293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
2092293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
209321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
2094293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
2095293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
2096293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
2097293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
2098293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
2099293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2100293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
21017729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
21025fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
2103cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
210421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
21050f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
2106d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
210721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
2108d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2109275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
211021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
21110f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
21120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
21135fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
21147729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
211524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
2116cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
2117cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
2118cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
21198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
21208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
21218d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
2122862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
21230aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
2124862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
2125862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
2126862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
21270aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2128862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
2129862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
2130862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
2131862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
213398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
21343471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                              bool isDoubleSpaced,
213598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
213698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
213798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
213898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
21393471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
214098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
214198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
214298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
214398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
214498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
21457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
214695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             unsigned Index,
214795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             bool isDoubleSpaced,
214895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             SMLoc S, SMLoc E) {
21497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
21507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
21517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
21527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
215395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
21547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
21557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
21567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
21577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
21587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
2159460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
2160460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
2161460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
2162460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
2163460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
2164460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
2165460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
2166460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2167460a90540b045c102012da2492999557e6840526Jim Grosbach
21683a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
216921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
2170762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
2171762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21733a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2174cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2175cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
21767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
21777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
21787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
21797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
21800d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
218157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
21827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
21833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
218421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2185e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2186e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2187e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2188e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2189e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
219057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2191e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
21927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
21937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
21947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
21957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
219616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2197f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2198f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2199f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
22007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
220121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
22027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2203f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2204f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2205f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2206762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2207762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2210706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2211706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
221221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2213706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2214706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2215706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2216706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2217706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2218a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2219a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
222021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2221a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2222a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2223a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2224a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
222821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2232584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2235a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2236a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2238b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2239fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
224021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
22416a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2242fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
224321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2244d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2245d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
224621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
22471a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    static const char *MaskStr[] = {
22481a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
22491a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
22501a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
225189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
225289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
225389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
225489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
225521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2256fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2257fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
225821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2259fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2260fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
22619b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
22629b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
22639b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
226421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2265584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2266584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
226721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2268fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2269fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
227021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2271706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2272706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
227321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
22746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2275e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
22766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2277fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
227821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2279f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2280f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2281f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2282f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2283f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2284f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
22857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
228621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2287a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2288a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2289a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2290a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2293a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
229521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
229650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2297fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
229821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2299580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2300580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2301e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
230221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
230392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2304efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2305efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2306efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
23070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
230821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
230992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2310efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2311efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2312efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
231392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
231421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
23157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
23167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
231721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2318293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2319293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2320293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
232121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
232221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
232321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
23248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
23258d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
23265fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
23275fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
23287729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
23297729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
23307729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
23318d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
23328d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
23338d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
23348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
23358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2336862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2337862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2338862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2339862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
234098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
234198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
234298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
234398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
23447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
23457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
23467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
23477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
234821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2349fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2350fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2351460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2352460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2353460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2354fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2355fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
23563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
23583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
23593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
23613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
23633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
236469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
236569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2366a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
23671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2368a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2369bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2370bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2371bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2372bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
23739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2374e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2375e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
23763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
23771355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
237818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
23797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2380d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2381590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
23820c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
23830c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
23840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
23850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
23860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
23870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
23880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
238940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
239040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
239140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
239240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
239340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
239440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
239540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
239640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
239740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
239840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
239940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
240040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
240140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
240240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
240340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
240440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
24050c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
24060c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2407a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2408aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // Check for aliases registered via .req. Canonicalize to lower case.
2409aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // That's more consistent since register names are case insensitive, and
2410aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // it's how the original entry was passed in from MC/MCParser/AsmParser.
2411aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
2412a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2413a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2414a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2415a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2416a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2417a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
241869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2419b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2420460a90540b045c102012da2492999557e6840526Jim Grosbach
2421e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2422e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2423d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
242419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
242519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
242619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
242719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
242819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
24290d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
24300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
24320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
24330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
24340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2435590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
24360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2437af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
24380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
24390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
24400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
24410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
24420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
24430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
24440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
24450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
244619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
24470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2448e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2449e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2450e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2451e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2452e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2453eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2454e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2455e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2457e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2458e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2459e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2461e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2463e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2464e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2465e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
24668a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
24678a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2468e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2469e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2470e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
247119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
247219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
247319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
247419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2475e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2476e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
247719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
247819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
247919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
248019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2481e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2482e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2483e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2484e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2485e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2486e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2487e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
248819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
248919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2490e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2491de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // shift by zero is a nop. Always send it through as lsl.
2492de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // ('as' compatibility)
2493de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      if (Imm == 0)
2494de626ad8726677328e10dbdc15011254214437d7Jim Grosbach        ShiftTy = ARM_AM::lsl;
2495e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
24961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2497e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
249819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
249919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
250019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
250119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
250219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
250319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2504e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
250519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
250619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2507e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2508e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
250992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
251092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2511af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
25120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
251392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
251492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
251592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
25160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
251719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
25180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
25190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
25200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
252150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
252250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
252350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2524e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2525e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2526e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
252750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
25281355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2529e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
25301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2531e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
253250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2533d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
253450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2536e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2537e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
253850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
253950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2540e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2541460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2542460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2543460a90540b045c102012da2492999557e6840526Jim Grosbach
2544460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2545460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2546460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2547460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2548460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2549460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2550460a90540b045c102012da2492999557e6840526Jim Grosbach
2551460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2552460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
2553460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2554460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2555ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (!MCE)
2556ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return TokError("immediate value expected for vector index");
2557460a90540b045c102012da2492999557e6840526Jim Grosbach
2558460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2559ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
2560ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return Error(E, "']' expected");
2561460a90540b045c102012da2492999557e6840526Jim Grosbach
2562460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2563460a90540b045c102012da2492999557e6840526Jim Grosbach
2564460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2565460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2566460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
256799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
256899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
256950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2570a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2571a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2572fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2573fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2574fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2575fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2576e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2577e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2578e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
25794d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default: return -1;
2580e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2581fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2582e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2583e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2584e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2585e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2586e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2587e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2588e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2589e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2590e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2591e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2592e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2593e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2594e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2595e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2596e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2597fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2598e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2599e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2602e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2603e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2604e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2605e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2606e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2607e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2608e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2610e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
261189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
261289df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
261389df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
261489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
261589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
261689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
261789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
261889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
261989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
262089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
262189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
262289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
262389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
262489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
262589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
262689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
262789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
262889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
262989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
263089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
263189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
263289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
263389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
263489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
263589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
263689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
263789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
263889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
263989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
264089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
264189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
264289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
264389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
264489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
264589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
264643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2647fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2648fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2649f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
265043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2651e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2652e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2653c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2654c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2655e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2656fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2657e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2658f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2659e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2660e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2661fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2662f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2664fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
266543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2666fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2667fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2668f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
266943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2670fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2671fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2672c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2673c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2674fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2675fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2676fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2677f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2678fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2679fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2680fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2681f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2682e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2683e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
26849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
26859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
26869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
26879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
26899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
26919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
26929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
26939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
26949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
26969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
26979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
26989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
26999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
27029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
27039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
27049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
27079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
27099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
27109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
27129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
27139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
27159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
27169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
27179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2718d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2719d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2720d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2721d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2722d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2723d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2724d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2725d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2726d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2727d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2728d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
2729d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2730d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2731d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2732d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2733d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2734d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2735d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2736d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2737d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2738d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2739d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2740ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2741ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2742ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2743ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2744ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2745ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2746ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2747ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2748ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2749ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2750ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2751ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2752ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
275325e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2754ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2755ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2756ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2757ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2758ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2759ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2760ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2761ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2762ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2763d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
276450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
27651355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
276618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2767a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2768e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2769d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2770d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
277116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2772d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2773d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2774d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2775d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2776d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2777d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2778ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2779ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2780ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2781ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2782ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2783ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2784ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2785ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2786ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2787ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
27881a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2789d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2790d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2791d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2792d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2793d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2794d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2795d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2796d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2797e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2798ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2799d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2800d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2801d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2802d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2803d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2804d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2805d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2806d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2807e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2808d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2811d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2812ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2813ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2814ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2815d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2816d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2817d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2818d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2819d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2820d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2821d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2822d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2823d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2824d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2825d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2826d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2827d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2828d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2829d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2830d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2831d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2832d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2833d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2834d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2835d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2836a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2837d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2838d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
28392d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2840ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2841ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2842ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2843ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2844ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2845ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2846d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2847d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2848d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2849d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2850a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg))
2851d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2852a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) {
2853a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2854a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2855a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2856a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2857d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2858d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2859d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2860d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2861d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2862d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2863d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2864ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2865ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2866d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2867d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2868d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2869d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2870d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2871d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2872e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
287327debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
287450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
287527debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
287627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
287727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
287827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
287927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
288027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
288127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
288250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2883d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2884d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
288598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
288698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
28877636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
28887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
288998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
289098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
289198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
289298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
289398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
289498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
289598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
289698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2897c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCExpr *LaneIndex;
2898c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    SMLoc Loc = Parser.getTok().getLoc();
2899c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (getParser().ParseExpression(LaneIndex)) {
2900c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "illegal expression");
2901c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
29027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
2903c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
2904c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (!CE) {
2905c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "lane index must be empty or an integer");
2906c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2907c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2908c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2909c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "']' expected");
2910c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2911c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2912c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Parser.Lex(); // Eat the ']'.
2913c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    int64_t Val = CE->getValue();
2914c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach
2915c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    // FIXME: Make this range check context sensitive for .8, .16, .32.
2916c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Val < 0 || Val > 7) {
2917c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "lane index out of range");
2918c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2919c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2920c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Index = Val;
2921c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    LaneKind = IndexedLane;
2922c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    return MatchOperand_Success;
292398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
292498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
292598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
292698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
292798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
2928862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2929862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2930862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
293198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
29327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
29335c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
29345c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
29355c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
29365c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
29375c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
29385c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
29395c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
29405c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
29415c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
29425c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
29437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
294498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
294598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
294698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
294798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
294898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29490aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
295098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
295198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
295298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29533471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
29543471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
295598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
295895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
295995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
296198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
29625c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
29635c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
29645c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
29655c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
29667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
296798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
296898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
296998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
297098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
297198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29720aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
297398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
297498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
297598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29763471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
29773471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
297898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
298195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
298295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29837636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
298498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
29855c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
29865c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
29875c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
29885c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
29895c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
29905c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
29915c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
2992862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
2993862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2994862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
2995862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
2996862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2997862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
2998862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
2999862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
3000862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3001862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3002862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
3003276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
3004c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
3005c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
3006c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
3007c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
3008c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
30090aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
30100aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
3011c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
3012c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
3013c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
30147636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
301598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
3016c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
3017e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
3018e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
3019e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
30200aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30210aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
30220aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
30230aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
30240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
30250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
30260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3027e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
3028e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
3029e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
3030e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
3031e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
3032e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3033e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3034e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
3035e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
3036e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
3037e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
3038e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
3039e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
3040e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
3041e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
3042e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
3043e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
3044e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3045e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3046e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
3047e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
3048e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
3049e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3050e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
305198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
305298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
30537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
30547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
305598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
30567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
305798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
305898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
305998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
306098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
3061e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
3062e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
3063e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
3064e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
3065e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
3066e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
3067862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
3068862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
3069862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
3070862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
3071862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
3072862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
3073862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3074862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3075c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
3076862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
3077862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
3078c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
3079c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
3080c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
3081c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
30820aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30830aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
30840aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
30850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
30860aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
30870aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
30880aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3089c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
3090c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
3091c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
3092c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
3093c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
3094c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
3095c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
309698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
309798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
30987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
309998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
31007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
310198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
31027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
310398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
310498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
310598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
3106c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
3107c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
31080aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
31090aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
31100aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
31110aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
31120aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
31130aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
31140aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
31150aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
3116862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
3117862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3118862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3119862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
312098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
312198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
31227636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
312398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
31247636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
312598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
31267636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
312798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
312898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
312998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
3130862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3131862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3133862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
3134862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
3135862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3136862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3137862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
3138862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
313998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
314098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
31410aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
31420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
314398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
314498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
314598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
31463471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                            (Spacing == 2),
314798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
314898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
31497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
31507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
315195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           LaneIndex,
315295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           (Spacing == 2),
315395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           S, E));
31547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
315598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
3156862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
3157862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
3158862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
315943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
3160f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
316143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3163706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3164706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3165706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
3166706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
3168706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
3169706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
3170032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
3171706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
3172032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
3173706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
3174706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
3175032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
3176706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
3177032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
3178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
3179706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
3180706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
3181706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3182706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
3183f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
3184706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3185706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3186706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3187f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3188706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
319043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
319243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3193a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3194a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3195a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3196a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
31982dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
31992dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
32012dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
32022dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
32032dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
32042dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
32052dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
32062dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
32072dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
32082dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
32092dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
32102dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
32112dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
32122dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
32132dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
32142dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
32152dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3216a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3217a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3218a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3219a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3220a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3221584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3222584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
322343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3224584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
322543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3228584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3231acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3232acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3233acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
3234acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
3235acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
3236acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
3237acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
3238acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
3239acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
3240acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
3241acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
3242acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
3243acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
3244acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
3245acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
3246acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
3247acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
3248acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
324918c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3250acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3251acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3252acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3253acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
3254acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3255acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
325618c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3257acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3258acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3259acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3260acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3261acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3262584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3263584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3264584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3265590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3266584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3267584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3268584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3269584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3270584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3271584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3276b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3277584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3278584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3279584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3280584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
32814b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3282584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3283584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3284584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3285bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
32864b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
328856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
328956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3290584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
33077784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
33087784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
33097784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
33107784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
33117784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
33127784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
33137784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3324f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3325f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3326f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3327f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3328f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3329f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3330f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3331f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3332f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3333590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3334590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3335f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3336f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3337f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3338f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3339f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3340f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3341f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
33428a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33438a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3344f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3345f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3346f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3347f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3348f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3349f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3350f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3351f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3352f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3353f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3354f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3355f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3356f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3357f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3358f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3359f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3360f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3361f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3362f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3371c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3372c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3373c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3374c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3375c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3376c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3377c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3378c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3379c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3380c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3381c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3382c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3383c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3384c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3385c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3386c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3387c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3388c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3389c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3390c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3391c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3392c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3393c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3394c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3395580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3396580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3397580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3398580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3399580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3400580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3401580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3402580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3403580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3404580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3405580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3406580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3408580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3409580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3410580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3411580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3412580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3414580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3416580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3417580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3418580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3419580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3420580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
34218a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
34228a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3423580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3424580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3425580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3426580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3427580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3428580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3429580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3430580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3431580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3432580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3434580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3440580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3441580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3442580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3444580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3445580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3446580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
34470afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
34480afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
34490afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
34500afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
34510afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3453580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3454580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3455580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3457580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3459580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3461580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3462580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3464580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3466580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
34677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
34687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
34697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
34707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
34717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
34727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
34737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3474326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3475326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
34767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3477326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3478326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
34797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
34807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
34828a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
34838a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
34847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
34857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
34877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
34887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
34907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
34917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
34927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
34937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
34957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
34967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
34977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
34987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
35027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
35037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
35047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
35057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
35067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
35077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
35117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
35127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
35147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
35157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3516293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3517293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3518293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3519293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
35208a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35218a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3522293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3523293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3524293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3525293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3526293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3527293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3528293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3529293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3530293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3531293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3532293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3533293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3534293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3535293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3536293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3537293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3538293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3539293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3540293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3541293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3542293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3543293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3544293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3545293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3546293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3547293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3548293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3549293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3550293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3551293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3552293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
35538a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35548a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3555293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3556293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3557293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3558293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3559293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3560293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3561293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3562293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3563293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3565293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3567293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3568293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3569293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3570293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3571293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3572293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3573293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3574293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3575293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3576293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3577293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3578293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3580293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3581293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3582293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3583293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
35847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
35857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
35867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3587f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3588f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3589f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
35907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
35917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
35927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
35937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
35947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
35957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
35967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
359716578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
35987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
35997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
36007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
36017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
36027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
36037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
360416578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
36057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
36067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
36077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
36087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
36097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
36107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
36117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
36127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
36137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
36147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
36157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
36167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3617f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3618f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
36190d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
36200d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
36210d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
36220d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
36230d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3624f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3625f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3626f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
36287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
36297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
36307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3631251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3632251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3633251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3634251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3635251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3636251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3637251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3638251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3639251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3640251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3641251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3642251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3643251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3644251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3645251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3646251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3647251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
36488a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
36498a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3650251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3651251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3652251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3653251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3654251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3655251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3656251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3657251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3658251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3659251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3660251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3661251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3662251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3663251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3667251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3668251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3670251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3671251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3672251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3673251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3674251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3675251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3678251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3680251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3681251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3682251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3683251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3684251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3685251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3686251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3687251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3688251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3689251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3690251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3691251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3692251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3693251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3694251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3695251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3696251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3699251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3700251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3701251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3702a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3703a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3704a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3705a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3706a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3707a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3708a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3709a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3710a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3711a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3712a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3713a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3714a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3715a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3716a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3717a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3718a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3719a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3720a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3721a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3722a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3723a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3724a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3725a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3726a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3727a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3728a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3729a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3730a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3731a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3732a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3733a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3734a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3737a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3738eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3739eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3740eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3741eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3742eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3743eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3744eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3745eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3746eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3747eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3748eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3749eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3750eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3751eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3752eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3753eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3754ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3755ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3756ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3757ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3758ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3759ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3760ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3761ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3762ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3763ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3764ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3765ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3766ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3767ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
37681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3770ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3771ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
37721355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3773ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3774ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3775ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3776ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3777ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3778ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
37797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3780ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3781ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3782ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3783ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
37849ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
37859ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
37869ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
37879ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
37889ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
37899ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37909ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
37919ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
37929ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
37939ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
37949ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
37959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
37969ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
37989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
37999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38009ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3801548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3802548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3803548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3804548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3805548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3806548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3807548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3808548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3809548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3810548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3811548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3812548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3813548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3814548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
38151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3816ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3817ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3818ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
38191355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3820ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3822ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3823548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3824548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3825548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
38277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
38287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
38297b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
38307b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38317b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
38327b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
38337b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
38347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38357b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
38367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38387b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
38397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
38417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
38427b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
38437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
38447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
38467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
38477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
38487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3850ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
38527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
38577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3858ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3859ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3860ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3861ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3863ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3865ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
38667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
38677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3869aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3870ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3871ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
38727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
38767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
38777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
38797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3880aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
38817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
38827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
38847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
38857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
38867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
38887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
38907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
38957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3896ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3897ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3898ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3899ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
39007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3901ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3902ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3903ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
39047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
39057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3906ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3907ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
39087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3909ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
39117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
39127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
39137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
39147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3915ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3916ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3917ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3918ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
39192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
39202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
39222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
39232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
39242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
39262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
39282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
39292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
39302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
39312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
39322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
39332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
39352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
39362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
393714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
393814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
393914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
394014605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
394114605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
394214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
394314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
394414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
394514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
394614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
394714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
394814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
394914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
395014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
395114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
395214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
395314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
395414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3955623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3956623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3957623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3958623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3959623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3960623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3961623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3962623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3963623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3964623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3965623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3966623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
3967623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
3968623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
396988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
397088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
397188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
397288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
397388ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
397488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
397588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
397688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
397788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
39787a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
39797a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
39807a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
39817a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
398288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
39837a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
398488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
398588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
398688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
398788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
39881b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
39891b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
39901b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
39911b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
39921b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
39931b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
39941b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
39951b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
39961b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
399788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
399888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
399988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
400088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
4001623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
400212431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
400312431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
400412431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
400512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
40066029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
400712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
400812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
400912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
401012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
401112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
401212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
401312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
401412431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
401512431329d617064d6e72dd040a58c1635cc261abJim Grosbach
401612431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
401712431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
401812431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
401912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
40206029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
402112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
402212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
402312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
402412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
402512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
402612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
402712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
402812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
402912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
403012431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
403112431329d617064d6e72dd040a58c1635cc261abJim Grosbach
40324334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
40334334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
40344334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40354334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
40364334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40374334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40384334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40394334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40406029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40414334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40424334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40434334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40444334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40454334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
40464334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
40474334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
40484334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40494334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
40504334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40514334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40524334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40534334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
40544334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
40554334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40566029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40574334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40584334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40594334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40604334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40614334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4062e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
40639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
406450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
40657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4066762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
406718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4068a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
4069762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
4070b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
4071a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
407218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
40731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
40747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
40757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
4076a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40770571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
40780571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
40790571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
40807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
40810571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
40827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
4083762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
4084b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
4085a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
408757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
408803f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
4089fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
4090fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
4091fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
4092fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4093fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
4094fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
4095fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
40967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
40977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
409850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
40997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
41007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
410150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
410257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
410357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
410457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
410557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
410657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
410757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
410857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
410957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
411057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
411157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
411257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
411357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
411457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
411557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
411657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
411757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
411857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
411957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
412057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
4121eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
4122eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4123eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
4124eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
412557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
412657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
412757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
412857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
412957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
413057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
413157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
413257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
413357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
413457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
413557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
413657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
413757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
413857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
413957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
414057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
414157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
414257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
414357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
414457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
414557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
414657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
414757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
414857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
414957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
415057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
415157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
415257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
41536cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
41546cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
41556cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
41568a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
41576cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
41588a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
41596cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
41607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
416150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
41620da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
41637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
41647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
41657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
416605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
41677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
41687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
41697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
41707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
41717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
41727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
41737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41740da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
41750da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
41760da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
41770da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
41780da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
41797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
41807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
41817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
41827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
41837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
418405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
41857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
41867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
41877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
418857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
418957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4190a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
41927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
41937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
41947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
41957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4196762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
41977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
41999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4200d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
42017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
42027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
42037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
42047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
42057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
42067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
42077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
42087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
42097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
42109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
42127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
42137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
42147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
42157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
42177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
42180d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
42197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
42207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
42210d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
42227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
42239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
422416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
42257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
42267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
42277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
42287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
42297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
42307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
423257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
42337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
42347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4235f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4236f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4237f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4238f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4239f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4240f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
42419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
42439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
42449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
42487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
42497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
42507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
42517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
425218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4253a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4254a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
425538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4256af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4257af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
42580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4259a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
42600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4261a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
42620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
42640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4265a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
42660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4267a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
42687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4269b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4270a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
42727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
42737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
42747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
42757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
42767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
42778a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
42788a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
42797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
42807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
42819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
42837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
42847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
42857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
42867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
42877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
42887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
42897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
42907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
42917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
42927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
42937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
42947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
42957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
42967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
42977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43029d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
43039d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
43049d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
430551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Anything that can accept a floating point constant as an operand
430651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // needs to go through here, as the regular ParseExpression is
430751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // integer only.
430851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  //
430951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // This routine still creates a generic Immediate operand, containing
431051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // a bitcast of the 64-bit floating point value. The various operands
431151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // that accept floats can check whether the value is valid for them
431251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // via the standard is*() predicates.
431351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
43149d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
43159d39036f62674606565217a10db28171b9594bc7Jim Grosbach
43168a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
43178a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
43189d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
43190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
43200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
43210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
43220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
43230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
43240e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
43250e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
43260e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
43270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
43280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
43290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
43300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
43310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
43320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
43330e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
43340e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
43359d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
43369d39036f62674606565217a10db28171b9594bc7Jim Grosbach
43379d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
43389d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
43399d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
43409d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
43419d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
43429d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
43439d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
4344ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  SMLoc Loc = Tok.getLoc();
43459d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
434651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
43479d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
43489d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
434951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    IntVal ^= (uint64_t)isNegative << 31;
43509d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
435151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
435251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          MCConstantExpr::Create(IntVal, getContext()),
435351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          S, Parser.getTok().getLoc()));
43549d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43559d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
435651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Also handle plain integers. Instructions which allow floating point
435751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // immediates also allow a raw encoded 8-bit value.
43589d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
43599d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
43609d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
43619d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
4362ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach      Error(Loc, "encoded floating point value out of range");
43639d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
43649d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
436551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    double RealVal = ARM_AM::getFPImmFloat(Val);
436651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
436751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
436851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        MCConstantExpr::Create(Val, getContext()), S,
436951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        Parser.getTok().getLoc()));
43709d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43719d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
43729d39036f62674606565217a10db28171b9594bc7Jim Grosbach
4373ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  Error(Loc, "invalid floating point immediate");
43749d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
43759d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
437651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
43779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
43789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
43791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4380fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4382fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4383fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4384fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4385f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4386f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4387fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4388f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4389f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4390f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4391f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4392f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4394a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4395146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4396146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
439750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
439819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
43991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
440050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
44010d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
440219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
44030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
440419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
440519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
44063cbe43fe69680df772d83947ced97ca445861213Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
44075cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
44085cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
44095cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
44105cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
44115cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
44125cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4413e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4414e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4415e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
441619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4417758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
441867b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
44196284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
442067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4424762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4425515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
442650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4427762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
442850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
442950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
443050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4431a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
44321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4433d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
44341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
44358a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
443663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4437079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4438079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
4439762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4440b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
444163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
4442515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
4443515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
444450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
444563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4446ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach    if (CE) {
4447ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      int32_t Val = CE->getValue();
4448ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      if (isNegative && Val == 0)
4449ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach        ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
445063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4451762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
445250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
445350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
445463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
44559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
44569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
44577597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
44587597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
44597597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
44601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
44619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44637597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
44647597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
44659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44677597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
44687597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
44699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
44707597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
44719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
44729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
44761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
44777597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
44781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
44797597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
44809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
44828a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
44839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
44849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
44869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
44879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
44889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
44899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
44919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
44927597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
44939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
44947597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
44959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
44969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
44979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
44989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
44999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
45009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
45029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
45039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
45069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
45079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
45089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4509352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4510352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4511352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4512badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
451389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
45141355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
45155f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
45165f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
451789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
451889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4519352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4520352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4522352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4523badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4524352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4525352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
45265f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
45275f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
45285f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
45295f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
45305f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
45315f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
45325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
45336849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
45346849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "fmuls")
4535352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4536badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
45373f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
45383f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4539ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
454071725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
454104d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
45422f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
45433f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
45443f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
45453f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
45463f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
45473f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
45483f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
45493f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
45503f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
45513f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
45523f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
45533f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
45543f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
45553f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
45563f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
45573f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
45583f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
45593f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
45603f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
45613f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
45623f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
45633f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
45643f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
45653f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
456652925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4567345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4568352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4569352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4570352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
457100f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
45725f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
45735f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
45745f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
457567ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
457648171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
45779c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach        Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
45781aa149f5acea364aa8bc9cfc3a167f78eff2e96bJim Grosbach        Mnemonic == "fmuls" || Mnemonic == "fcmps" ||
4579e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4580352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4581352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4582352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4583352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4584a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4585a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4586a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4587a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4588a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4589a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4590a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4591a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4592a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4593a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4594a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4595a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4596a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4597a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4598a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
459989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
460089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
460189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
460289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
460389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
460489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4605352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4606352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
46073771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
46083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
46093771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
46103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
46113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4612fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
46131355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4614fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4615eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4616eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
46173443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4618eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4619d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4620eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4621d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
46223443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4623d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4624d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4625eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4626fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4627eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
46283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4629eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4630eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4631eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4632eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4633ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4634ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
46350780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
46362bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
46372bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
46382bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
46394af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
46404af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
46411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
46423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4643fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
46443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4645fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4646fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4647fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
464863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4649fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4650fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4651badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4652badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4653d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4654d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
465520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
465620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4657d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4658d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4659d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4660d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4661d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4662d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4663d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4664d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4665d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
46668adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4667d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4668d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4669d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4670d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
46713912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
46723912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
46733912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
46743912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
46753912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
46763912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
46773912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
46783912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
467972f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
468020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
468120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
468220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4683f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4684f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4685f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
468672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
468772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
468872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
468920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
469020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
469120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
469272f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4693f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4694f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
469520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
469620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
469720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4698f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4699f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
470020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
470120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
470220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
470320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
470420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
470520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
470620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
470712a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // check against T3. If the second register is the PC, this is an
470812a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // alternate form of ADR, which uses encoding T4, so check for that too.
470920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
471020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
471112a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC &&
471220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
471320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
471420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
471520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
471620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
471764944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
471820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
471920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
472020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
472120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
472220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
472320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
472420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
472520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
472620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
472764944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
472864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
472964944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
473064944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
473164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
473264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
473364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
473464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
473564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
473664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
473764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
473864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
473964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
474064944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47411de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
474264944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
474364944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
474464944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
474564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
474664944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
474764944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
474864944f48a1164c02c15ca423a53919682a89074cJim Grosbach
47497f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
47507f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
47517f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
47527f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
47537f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
47547f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
47557f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
47567f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
47577f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
47587f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
47597f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47607f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
47617f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
47627f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
476364944f48a1164c02c15ca423a53919682a89074cJim Grosbach
476420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4765f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4766f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4767f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4768f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4769f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4770f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4771f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
477272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
477372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
477472f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
477572f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
47763912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4777d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4778d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4779d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
47807aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
47817aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
47827aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
47837aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
47847aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
47857aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
47867aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
47877aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
47887aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
47897aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
47907aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
47917aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
47927aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
47937aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
47947aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
47957aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
479621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4797badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4798badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4799badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
480021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
480121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
480221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
480321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
480421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
480521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
480621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
480721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4808a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4809a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4810a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4811a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4812a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4813a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4814a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4815a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4816a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4817badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4818badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4819ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4820badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4821352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4822352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4823a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4824352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
482589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
48261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
482789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4828badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
48290c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
48300c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
48310c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
48320c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
48330c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
48340c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4835ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4836ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
483789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
483889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
483989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
484089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
484189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
484289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4843f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4844f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4845f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4846f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4847f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
484889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
484989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
485089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
485189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
485289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4853f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
485489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
485589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
485689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
485789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
485889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4859f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
486089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
486189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4862ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4863ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
48649717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
48653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
48663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
48673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
48683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
48693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
48703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
48713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
48723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
48731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
48743771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
487533c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
487633c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
487733c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
487833c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4879ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
488033c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
488133c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4882c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4883c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4884c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4885c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4886c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4887c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4888c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
488933c16a27370939de39679245c3dff72383c210bdJim Grosbach
48903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4891f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4892f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
48933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4894f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4895f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
48963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
48973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
48983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4899f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4900f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
49013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4902f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4903badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4904345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4905a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4906a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4907a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4908a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4909a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4910a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4912345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
49135747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
49145747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
49155747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4917a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
49187aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
49197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
49207aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
49217aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
49227aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
49237aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
492481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
492581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
492681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
492781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
49285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
49295747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
49305747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
49315747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4932a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
49331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4934cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4935cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4936cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4937a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4938a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4939b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4940a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4941a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
49421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4943cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4944cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4945cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4946a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4947a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
494816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4949cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4950186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4951cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4952186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4953cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4954146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
495534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4956ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4957d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4958d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4959d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
496020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
496120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
496220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
496320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
496420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4965ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4966ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
4967ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
4968ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
4969ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4970cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
4971cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
4972cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
497321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
497421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
4975cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
4976cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
4977cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4978cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
4979cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
4980cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
4981857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
4982857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
4983857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
4984857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
4985857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
4986857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
4987857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4988857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4989857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4990857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
4991857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
4992857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
499368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
499468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
499568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
499668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
499768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
499868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
499968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
500068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
500168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
500268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
500368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5004857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
5005857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
5006857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
5007934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
500855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
500955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
5010934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
501155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
501255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
5013934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5014934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5015934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
501655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
501755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
5018d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
5019d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
5020d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
502155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
5022d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
5023934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
5024934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5025934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
5026934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
5027934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
5028934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
50299898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
5030ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5031ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5032189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
5033aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
5034aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
5035aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
5036aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
5037aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
5038aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
5039aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
5040aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
5041aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
5042aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
5043aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
5044aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
5045aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
5046aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
5047aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
5048aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
5049aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
5050aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
505176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
505276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
505376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
505476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
505576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
505676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
505776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
505876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
505976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
506076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
506176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
5062f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
5063f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
5064f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
5065f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
50661a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5067f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
50681a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
5069f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
5070f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
5071f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5072189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
5073189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
5074189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
5075189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
50761a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
5077f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
5078f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
507974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // NOTE: BKPT instruction has the interesting property of being
508074423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // allowed in IT blocks, but not being predicable.  It just always
5081b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
508274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT &&
508374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      Inst.getOpcode() != ARM::BKPT) {
5084f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
5085f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
5086f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
5087f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
5088a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
5089f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
5090f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
5091f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
5092f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
5093f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
5094f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
5095f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
5096f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
5097f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
5098f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
5099f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
5100f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
5101f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
5102f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
5103f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
5104f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
5105f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
5106c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
5107f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
5108f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
510951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
511051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
5111f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
5112f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5113189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
51142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
51152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
51162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
5117189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
5118189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5119189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
5120189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5121189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
5122189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5123189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
5124189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5125189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
512614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
512714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
512814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
512914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
513014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
513114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
513214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
513314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
513414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
513553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
513653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
5137189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
5138189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5139189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5140189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
5141189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
514214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5143189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
5144189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5145189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5146fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
5147fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
5148fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
5149fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
5150fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
5151fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
5152fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
5153fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
515400c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
5155fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
515693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
515776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
515876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
515976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
516076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
516176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
516293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
516393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
516493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
51657260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
51667260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
51677260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
5168aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
516976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
5170aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
5171aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
517293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
517376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
517493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
517593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
517676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
517776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
5178aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
51797260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
51807260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
51817260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
518293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
518393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
518493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
518576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
518676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
518776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
518876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
518976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
519076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
519176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
51925402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
51935402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
51945402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
51956dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5196aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
51975402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
51985402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5199aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5200aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
52016dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
52026dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
52036dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
52055402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
52065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5207aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5208aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
52096dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
52106dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
52111e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
52121e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
52138213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
52141e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
52151e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
52161e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
52171e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5218189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5220189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5222189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5223d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
522484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
522584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  default: assert(0 && "unexpected opcode!");
52269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
52277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
52287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
52297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
52307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
52317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
52327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
52337945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_8:  Spacing = 1; return ARM::VST1LNd8;
52347945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
52357945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
52369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
52387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
52397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
52407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
52417945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
52427945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
52437945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
52447945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
52457945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
52467945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
52477945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
52487945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
52497945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
52507945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_8:  Spacing = 1; return ARM::VST2LNd8;
52517945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
52527945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
52537945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
52547945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
5255d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
52564adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  // VST3LN
52577945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
52587945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
52597945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
52607945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
52617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
52627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
52637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
52647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
52657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
52667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
52677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_8:  Spacing = 1; return ARM::VST3LNd8;
52687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
52697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
52707945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
52717945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
52724adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
5273d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3
52747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
52757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
52767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
52777945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
52787945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
52797945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
52807945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
52817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
52827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
52837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
52847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
52857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
52867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_8:  Spacing = 1; return ARM::VST3d8;
52877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
52887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
52897945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_8:  Spacing = 2; return ARM::VST3q8;
52907945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
52917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
5292539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
529388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  // VST4LN
529488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
529588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
529688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
529788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
529888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
529988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
530088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
530188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
530288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
530388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
530488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:  Spacing = 1; return ARM::VST4LNd8;
530588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
530688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
530788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
530888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
530988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
5310539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4
5311539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5312539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5313539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5314539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5315539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5316539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5317539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5318539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5319539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5320539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5321539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5322539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5323539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:  Spacing = 1; return ARM::VST4d8;
5324539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
5325539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
5326539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:  Spacing = 2; return ARM::VST4q8;
5327539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
5328539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
532984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
533084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
533184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
5332d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
53337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
53347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  default: assert(0 && "unexpected opcode!");
53359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
53367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
53377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
53387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
53397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
53407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
53417945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
53427945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_8:  Spacing = 1; return ARM::VLD1LNd8;
53437945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
53447945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
53459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
53469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
53477945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
53487945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
53497945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
53507945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
53517945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
53527945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
53537945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
53547945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
53557945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
53567945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
53577945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_8:  Spacing = 1; return ARM::VLD2LNd8;
53587945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
53597945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
53607945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
53617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
53623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
53635e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP
53645e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
53655e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
53665e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
53675e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
53685e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPq16_UPD;
53695e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
53705e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
53715e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
53725e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
53735e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
53745e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
53755e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
53765e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:  Spacing = 1; return ARM::VLD3DUPd8;
53775e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
53785e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
53795e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
53805e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
53815e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
53825e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
53833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  // VLD3LN
53847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
53857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
53867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
53877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
53887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
53897945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
53907945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
53917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
53927945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
53937945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
53947945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_8:  Spacing = 1; return ARM::VLD3LNd8;
53957945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
53967945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
53977945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
53987945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
5399c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
5400c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3
54017945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
54027945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
54037945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
54047945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
54057945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
54067945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
54077945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
54087945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
54097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
54107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
54117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
54127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
54137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_8:  Spacing = 1; return ARM::VLD3d8;
54147945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
54157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
54167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;
54177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
54187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
54198abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
5420e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  // VLD4LN
5421e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5422e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5423e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5424e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNq16_UPD;
5425e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5426e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5427e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5428e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5429e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
5430e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5431e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:  Spacing = 1; return ARM::VLD4LNd8;
5432e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
5433e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
5434e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
5435e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
5436e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
5437a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP
5438a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5439a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5440a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5441a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
5442a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
5443a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5444a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5445a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5446a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5447a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
5448a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
5449a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5450a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:  Spacing = 1; return ARM::VLD4DUPd8;
5451a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
5452a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
5453a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
5454a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
5455a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
5456a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
54578abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  // VLD4
54588abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
54598abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
54608abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
54618abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
54628abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
54638abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
54648abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
54658abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
54668abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
54678abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
54688abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
54698abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
54708abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8;
54718abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
54728abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
54738abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8;
54748abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
54758abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
54767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
54777636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
54787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
547983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5480f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5481f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5482f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
54830b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  // Aliases for alternate PC+imm syntax of LDR instructions.
54840b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRpcrel:
54850b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRpci);
54860b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
54870b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRBpcrel:
54880b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRBpci);
54890b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
54900b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRHpcrel:
54910b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRHpci);
54920b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
54930b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSBpcrel:
54940b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSBpci);
54950b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
54960b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSHpcrel:
54970b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSHpci);
54980b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
54999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
55008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
55018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
55028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32: {
550384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
550484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
550584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
55065b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5507d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
550884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
550984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
551084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
551184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
551284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
551384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
551484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
551584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
551684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
551784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
551884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
55199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55208b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
55218b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
55228b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
55238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
55248b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32: {
55259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
55269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
55285b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5529d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
55309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55355b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55365b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
55379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
55409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
55419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
55429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
55434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
55444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:
55454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16:
55464adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32:
55474adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16:
55484adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: {
55494adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
55504adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55514adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
55524adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
55534adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
55544adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55554adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55564adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55574adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55584adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55594adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55604adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
55614adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55624adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
55634adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55644adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55654adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
55664adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
55674adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
55684adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
55694adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
557088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:
557188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16:
557288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32:
557388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16:
557488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: {
557588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
557688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
557788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
557888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
557988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
558088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
558188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
558288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
558388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
558488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
558588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
558688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
558788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
558888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
558988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
559088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
559188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
559288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
559388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
559488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
559588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
559688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
559788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
55988b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
55998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
56008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: {
560184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
560284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
560384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
56045b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5605d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
560684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
560784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
560884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
560984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
561084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
561184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
561284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
561384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
561484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
561584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
561684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
56179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56188b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
56198b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
56208b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
56218b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
56228b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: {
56239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
56249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
56265b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5627d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
56289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56335b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56345b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
56359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
56399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
56409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
56414adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
56424adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:
56434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16:
56444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32:
56454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16:
56464adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: {
56474adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
56484adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56494adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
56504adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
56514adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
56524adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56534adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56544adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56554adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56564adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56574adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56584adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
56594adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56604adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
56614adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56624adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56634adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56644adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
56654adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
56664adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
56674adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
566888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:
566988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16:
567088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32:
567188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16:
567288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: {
567388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
567488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
567588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
567688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
567788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
567888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
567988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
568088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
568188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
568288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
568388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
568488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
568588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
568688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
568788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
568888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
568988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
569088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
569188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
569288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
569388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
569488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
569588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
56968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
56978b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
56988b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32: {
569984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
570084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
570184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
57025b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5703d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
570484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
570584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
570684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
570784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
570884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
570984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
571084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
571184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
571284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
57139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
57148b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
57158b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
57168b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
57178b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
57188b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32: {
57199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
57209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
57225b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5723d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57275b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57285b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
57299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
57339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
57349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
57354adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
57364adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_8:
57374adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_16:
57384adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_32:
57394adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_16:
57404adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_32: {
57414adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
57424adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
57444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
57454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57464adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57474adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57484adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57494adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57504adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
57514adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57524adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
57534adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57544adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57554adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
575688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
575788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
575888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
575988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
576088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:
576188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16:
576288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32:
576388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16:
576488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: {
576588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
576688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
576788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
576888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
576988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
577088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
577188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
577288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
577388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
577488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
577588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
577688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
577788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
577888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
577988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
578088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
578188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57824adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
57834adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
57844adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
57854adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
57869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
57878b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
57888b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
57898b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: {
5790872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5791872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5792872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
579395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5794d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5795872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5796872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5797872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5798872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5799872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5800872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5801872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5802872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5803872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5804872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5805872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5806872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
58079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58088b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
58098b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
58108b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
58118b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
58128b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: {
58139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
581695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5817d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
58189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
581995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
582095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
58219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
58259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
582695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
582795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
58289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
58309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
58319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
58329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
58339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
58349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
58363a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
58373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
58383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
58393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: {
58403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
58413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
58423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
58433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
5844d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
58453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58463a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58473a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
58483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5849c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
58503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
58543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
58553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
58573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5858c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
58593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
58613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
58623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
58633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
58643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
58653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
5866e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:
5867e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16:
5868e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32:
5869e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16:
5870e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: {
5871e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
5872e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
5873e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
5874e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
5875e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5876e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5877e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5878e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5879e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5880e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5881e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5882e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5883e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5884e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5885e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5886e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5887e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5888e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5889e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5890e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5891e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5892e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5893e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5894e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5895e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5896e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5897e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
5898e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
5899e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
5900e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
59018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
59028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
59038b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: {
5904872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5905872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5906872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
590795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5908d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5909872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5910872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5911872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5912872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5913872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
5914872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5915872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5916872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
5917872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
5918872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5919872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5920872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
59219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59228b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
59238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
59248b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
59258b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
59268b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: {
59279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
59289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
593095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5931d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
593395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
593495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
59369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
59399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
594095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
594195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
59469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
59479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
59489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
59503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
59513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
59523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
59533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: {
59543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
59553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
59563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
59573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
5958d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
59623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5963c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
59643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
59653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
59683a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
59693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
59713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5972c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
59733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
59773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
59783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
59793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
5980e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:
5981e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16:
5982e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32:
5983e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16:
5984e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: {
5985e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
5986e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
5987e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
5988e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
5989e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5990e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5991e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5992e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5993e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5994e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5995e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5996e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5997e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5998e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5999e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6000e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6001e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6002e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6003e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6004e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6005e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6006e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6007e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6008e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6009e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6010e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6011e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6012e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6013e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6014e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
60158b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
60168b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
60178b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32: {
60187636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
60197636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
60207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
602195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6022d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60247636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60257636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60267636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60277636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
60317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
60327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
60339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
60348b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
60358b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
60368b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
60378b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
60388b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32: {
60399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
60409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
60419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
604295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6043d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
604595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
604695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
605095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
605195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
60569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
60579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
60583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
60593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
60603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
60613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
60623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
60633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32: {
60643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
60653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
60663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
60673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6068d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6073c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6080c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60823a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
60853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
60863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
60873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6088e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:
6089e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16:
6090e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32:
6091e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16:
6092e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: {
6093e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6094e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6095e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6096e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6097e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6098e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6099e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6100e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6101e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6102e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6103e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6104e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6105e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6106e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6107e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6108e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6109e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6110e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6111e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6112e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6113e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6114e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6115e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6116e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6117e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6118e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6119e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6120e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
61215e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP single 3-element structure to all lanes instructions.
61225e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:
61235e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16:
61245e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32:
61255e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8:
61265e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16:
61275e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: {
61285e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61295e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61305e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61315e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61325e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61335e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61345e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61355e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61365e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61375e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61385e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
61395e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
61405e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61415e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
61425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
61435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
61445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:
61455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16:
61465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32:
61475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8:
61485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16:
61495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: {
61505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
61605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61615e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61625e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
61635e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
61645e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61655e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
61665e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
61675e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
61685e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:
61695e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16:
61705e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32:
61715e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8:
61725e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16:
61735e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: {
61745e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61755e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61765e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61775e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61785e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61795e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61805e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61815e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61825e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61835e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
61845e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61855e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
61865e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61875e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61885e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61895e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
61905e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
61915e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
6192c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3 multiple 3-element structure instructions.
6193c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_8:
6194c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_16:
6195c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_32:
6196c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_8:
6197c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_16:
6198c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_32: {
6199c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6200c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6201d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6202c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6203c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6204c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6205c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6206c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6207c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6208c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6209c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6210c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6211c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6212c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6213c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6214c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6215c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:
6216c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16:
6217c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32:
6218c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:
6219c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16:
6220c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: {
6221c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6222c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6223d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6224c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6225c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6226c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6227c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6228c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6229c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6230c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6231c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6232c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6233c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6234c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6235c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6236c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6237c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6238c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6239c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:
6240c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_16:
6241c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_32:
6242c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:
6243c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_16:
6244c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: {
6245c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6246c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6247d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6248d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6249d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6250d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6251d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6252d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6253d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6254d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6255d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6256d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6257d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6258d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6259d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6260d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6261d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6262d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6263a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP single 3-element structure to all lanes instructions.
6264a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:
6265a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16:
6266a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32:
6267a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8:
6268a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16:
6269a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: {
6270a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6271a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6272a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6273a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6274a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6275a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6276a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6277a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6278a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6279a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6280a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6281a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6282a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6283a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6284a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6285a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6286a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6287a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6288a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:
6289a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16:
6290a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32:
6291a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8:
6292a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16:
6293a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: {
6294a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6295a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6296a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6297a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6298a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6299a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6300a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6301a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6302a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6303a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6304a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6305a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6306a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6307a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6308a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6309a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6310a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6311a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6312a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6313a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6314a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:
6315a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16:
6316a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32:
6317a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8:
6318a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16:
6319a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: {
6320a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6321a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6322a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6323a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6324a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6325a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6326a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6327a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6328a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6329a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6330a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6331a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6332a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6333a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6334a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6335a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6336a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6337a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6338a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6339a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6340a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4 multiple 4-element structure instructions.
63418abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:
63428abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16:
63438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32:
63448abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:
63458abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16:
63468abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: {
63478abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
63488abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
63498abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63508abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63518abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63528abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
63538abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63548abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
63558abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63568abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
63578abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63588abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63598abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63608abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63618abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
63628abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
63638abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
63648abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
63658abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:
63668abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16:
63678abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32:
63688abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:
63698abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16:
63708abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: {
63718abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
63728abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
63738abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63748abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63758abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63768abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
63778abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63788abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
63798abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63808abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
63818abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63828abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
63838abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63848abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
63858abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63868abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63878abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
63888abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
63898abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
63908abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
63918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:
63928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16:
63938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32:
63948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:
63958abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16:
63968abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: {
63978abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
63988abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
63998abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
64008abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
64018abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64028abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
64038abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64048abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
64058abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64068abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
64078abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
64088abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
64098abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
64108abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
64118abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
64128abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
64138abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
64148abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
64158abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
64168abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
6417d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3 multiple 3-element structure instructions.
6418d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_8:
6419d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_16:
6420d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_32:
6421d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_8:
6422d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_16:
6423d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_32: {
6424d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6425d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6426d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6427d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6428d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6429d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6430d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6431d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6432d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6433d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6434d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6435d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6436d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6437d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6438d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6439d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6440d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:
6441d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16:
6442d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32:
6443d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:
6444d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16:
6445d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: {
6446d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6447d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6448d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6449d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6450d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6451d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6452d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6453c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6454c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6455c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6456c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6457c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6458d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6459d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6460d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6461d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6462d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6463d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6464d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_8:
6465d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_16:
6466d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_32:
6467d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_8:
6468d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_16:
6469d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_32: {
6470d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6471d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6472d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6473c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6474c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6475c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6476c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6477d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6478d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6479d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6480d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6481d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6482c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6483c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6484c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6485c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6486c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6487c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6488539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4 multiple 3-element structure instructions.
6489539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:
6490539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16:
6491539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32:
6492539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:
6493539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16:
6494539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: {
6495539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6496539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6497539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6498539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6499539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6500539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6501539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6502539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6503539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6504539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6505539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6506539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6507539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6508539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6509539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6510539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6511539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6512539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6513539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:
6514539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16:
6515539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32:
6516539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:
6517539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16:
6518539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: {
6519539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6520539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6521539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6522539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6523539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6524539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6525539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6526539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6527539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6528539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6529539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6530539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6531539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6532539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6533539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6534539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6535539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6536539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6537539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6538539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6539539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:
6540539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16:
6541539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32:
6542539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:
6543539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16:
6544539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: {
6545539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6546539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6547539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6548539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6549539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6550539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6551539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6552539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6553539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6554539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6555539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6556539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6557539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6558539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6559539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6560539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6561539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6562539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6563539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6564539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6565863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
65662cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVsr:
65672cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVSsr: {
65682cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
65692cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // whether we're in an IT block if the register operands are low
65702cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // registers.
65712cc5cda464e7c936215281934193658cb799c603Jim Grosbach    bool isNarrow = false;
65722cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
65732cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
65742cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(2).getReg()) &&
65752cc5cda464e7c936215281934193658cb799c603Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
65762cc5cda464e7c936215281934193658cb799c603Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
65772cc5cda464e7c936215281934193658cb799c603Jim Grosbach      isNarrow = true;
65782cc5cda464e7c936215281934193658cb799c603Jim Grosbach    MCInst TmpInst;
65792cc5cda464e7c936215281934193658cb799c603Jim Grosbach    unsigned newOpc;
65802cc5cda464e7c936215281934193658cb799c603Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
65812cc5cda464e7c936215281934193658cb799c603Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
65822cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
65832cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
65842cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
65852cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
65862cc5cda464e7c936215281934193658cb799c603Jim Grosbach    }
65872cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.setOpcode(newOpc);
65882cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
65892cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isNarrow)
65902cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
65912cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
65922cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65932cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
65942cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
65952cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
65962cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (!isNarrow)
65972cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
65982cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
65992cc5cda464e7c936215281934193658cb799c603Jim Grosbach    Inst = TmpInst;
66002cc5cda464e7c936215281934193658cb799c603Jim Grosbach    return true;
66012cc5cda464e7c936215281934193658cb799c603Jim Grosbach  }
6602863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
6603863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
6604863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
6605863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
6606863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
6607863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
6608863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6609863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6610863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
6611863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
6612863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
6613863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
6614863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
6615863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6616863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
6617863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
6618863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
6619863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
6620520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
6621863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
6622863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
6623863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (Ammount == 32) Ammount = 0;
6624863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
6625863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
6626863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
6627863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6628863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6629863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6630520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    if (newOpc != ARM::t2RRX)
6631520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Ammount));
6632863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6633863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6634863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
6635863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6636863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6637863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
6638863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
6639863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
6640863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
664123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
664223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
664323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
664423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
664523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
664623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
664723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
664823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
664923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
665023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
665123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
665223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
665323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
665423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
665523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
665623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
665723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
665823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
665923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
666023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
666123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
666223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
666323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
666423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
666523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
6666ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
6667ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
6668ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
6669ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
6670ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
6671ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
6672ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6673ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
6674ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
6675ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
6676ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
6677ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
6678ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
667948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
6680ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
6681ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
668271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
6683ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
668471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
668571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6686ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
6687ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
668871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
668971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
669071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
669171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
669283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
669371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
669448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
669548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
669648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
669748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
669848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
669948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
670048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
670148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
670248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
670348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
670448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
670548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
670648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
67070352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
67080352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
67090352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
67100352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
67110352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
67120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
67130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
67140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
67150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
67160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
67170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
67180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
67190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
67200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
67210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
67220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
67230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
67240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
67250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
67260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
67270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
67280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
67290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
67300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
67310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
67320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
67330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
67340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
67350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
67360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
67370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
67380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
6739f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
6740f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
6741f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
6742f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
6743f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
6744f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
6745f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
6746f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6747f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6748f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
6749f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
6750f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
6751f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6752f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6753f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
675483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6755f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
6756f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
6757f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
6758f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
6759f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
6760f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
6761f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
6762f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
6763f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
6764f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6765f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6766f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
6767f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
6768f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6769f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6770f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
6771f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
6772f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
6773da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
6774da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
6775da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
6776da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
6777da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6778da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6779da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
6780da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6781da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
6782da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
6783da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
6784da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
6785da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
6786da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6787da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6788da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
6789da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6790da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
679189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
67920f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
67930f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
67940f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
67950f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
679683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
679789e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
679883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
679983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
680089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
6801f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
6802f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
6803f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
6804f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
6805f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
680683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
6807f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
680883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
680983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6810f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
6811927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
6812927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
6813927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
6814927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
6815927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
6816927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
6817927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
6818713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
6819713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
6820927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
6821927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
6822927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
6823927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6824927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6825927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
6826927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
6827927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6828927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
6829927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
6830927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
683151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
683251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
683383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
683451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
683583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
683683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
683751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
683851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
683951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
684083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
684151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
684283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
684383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
684451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
6845c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
6846a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
684783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
6848c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
684983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
685083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6851c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
6852395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
6853395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
685483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
6855395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
685683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
685783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
68583ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
685976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
686076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
686176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
686276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
686376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
686476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
686576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
686676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
686776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
686876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
686976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
687076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
687176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
687276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
687376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
687476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
687576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
687676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
687776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
687876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
687976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
688083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
688176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
688276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
688376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
68848213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
68858213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
68868213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
68878213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
68888213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
68898213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
68908213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
68918213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
68928213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
68938213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
689483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
68958213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
68968213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
68978213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
68985402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
68995402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
69005402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
69015402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
69025402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
69035402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
690483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
69055402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
69065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
69075402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
69085402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
69095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
691083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
69115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
69125402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
69135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
69145402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
691583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
69165402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
69175402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
69185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
69195402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
69205402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
692183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
69225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
69231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
69241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
69251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
69261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
69271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
6928c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
6929c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
6930c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
69311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
69321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
69331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
69341ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
69351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
69361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
69371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
69381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
69391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
69401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
69411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
694283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
69441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
69451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
69461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
69471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
69481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
69491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
69501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
69511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
69521ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
69531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
69541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
69551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
69561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
69571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
69581ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
69591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
69601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
69611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
69621ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
696383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
69651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
69661ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
6967326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
696850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
696950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
697050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
6971326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
6972326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
6973326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6974326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6975326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
6976326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
6977326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
697850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
697950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
698050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
698150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
698250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
698350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
698450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
698550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
6986326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
6987326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
6988326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
6989326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
6990326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
6991326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6992326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
6993326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
699483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6995326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
6996326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
6997326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
699804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  case ARM::MOVsi: {
699904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
700004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (SOpc == ARM_AM::rrx) return false;
700104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
700204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      // Shifting by zero is accepted as a vanilla 'MOVr'
700304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      MCInst TmpInst;
700404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
700504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
700604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
700704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
700804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
700904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
701004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      Inst = TmpInst;
701104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      return true;
701204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    }
701304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    return false;
701404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  }
70158d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ANDrsi:
70168d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ORRrsi:
70178d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::EORrsi:
70188d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::BICrsi:
70198d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::SUBrsi:
70208d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ADDrsi: {
70218d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    unsigned newOpc;
70228d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
70238d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (SOpc == ARM_AM::rrx) return false;
70248d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    switch (Inst.getOpcode()) {
702519055cc2712223f6834fc3cf5b547803ba83f066Matt Beaumont-Gay    default: assert(0 && "unexpected opcode!");
70268d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
70278d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
70288d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::EORrsi: newOpc = ARM::EORrr; break;
70298d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::BICrsi: newOpc = ARM::BICrr; break;
70308d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
70318d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
70328d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
70338d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    // If the shift is by zero, use the non-shifted instruction definition.
70348d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) {
70358d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      MCInst TmpInst;
70368d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.setOpcode(newOpc);
70378d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
70388d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
70398d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
70408d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
70418d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
70428d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(6));
70438d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      Inst = TmpInst;
70448d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      return true;
70458d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
70468d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    return false;
70478d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  }
704874423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  case ARM::ITasm:
704989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
705089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
705189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
705289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
705389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
705489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
705589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
705689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
705789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
7058f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
7059f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
706089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
706189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
706289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
706389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
706489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
706589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
706689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
7067f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
7068f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
7069f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
7070f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
7071f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
7072f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
7073f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
7074f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
707589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
707689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
7077f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
707883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
7079f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
7080f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
708147a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
708247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
708347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
7084194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
70851a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
708647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
708747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
708847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
708947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
709047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
709147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
709247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
709347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
709447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
709547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
709647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
709747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
709847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
709947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
710047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
710147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
7102f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
7103f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
710447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
7105f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
7106f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
7107f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
710847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
7109194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
7110194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
7111194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
7112194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
7113194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
7114194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
7115194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
71164ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
7117194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
7118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
7119194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
712047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
712147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
712247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
7123fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
7124fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
7125fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7126fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
7127fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
7128fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
712919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
7130193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
7131193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
713219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
7133e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
7134189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
7135189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
7136a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
7137a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
7138a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
7139a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
7140189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
7141a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
7142189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
7143f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
714483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
714583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
714683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
714783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
714883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
7149f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
7150a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
7151a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
7152a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
7153a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
7154a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
715574423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
715674423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // doesn't actually encode.
715774423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    if (Inst.getOpcode() == ARM::ITasm)
715874423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      return false;
715974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach
716042e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Inst.setLoc(IDLoc);
7161fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
7162fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
7163e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
7164e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
7165e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
7166e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
7167e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
7168e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
7169e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
7170e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
717116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7172e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
7173e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
7174e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
717516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7176e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
7177e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
7178e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
717947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
7180b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
718188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
718288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
7183f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
7184f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
718547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
718647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
7187194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
7188194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
7189194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
7190194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
7191fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
719216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7193c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
7194fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
7195fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
71961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
7197ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
7198ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
7199ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
72001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
7201515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
72021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
72039a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
72049a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
7205515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
72061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
7207515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
72081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
7209515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
72101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
7211a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
7212a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
7213d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".arch")
7214d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveArch(DirectiveID.getLoc());
7215d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".eabi_attribute")
7216d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveEabiAttr(DirectiveID.getLoc());
7217ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
7218ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7219ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
72201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
7221ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
72221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
7223ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
7224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
7225ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
7226ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
7227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
7228ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7229aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
7230ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7231ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
7232ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
723316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7234ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
7235ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
7236ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
7237b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
7238ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
7239ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
7240ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7241b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7242ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
7243ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7244ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
72451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
7246515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
72471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
7248515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
7249515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7250b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7251515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
72529a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
72539a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
72549a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
72559a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
72569a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
72579a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
72589a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
72599a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
72609a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
72619a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
72629a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
72639a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
72649a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
72659a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
72669a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
72679a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7268515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7269515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
72711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
7272515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
72731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
72746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
72756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
72766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
7277de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  bool needFuncName = true;
72786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7279de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Darwin asm has (optionally) function name after .thumb_func direction
72806469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
72816469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
72826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
7283de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    if (Tok.isNot(AsmToken::EndOfStatement)) {
7284de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
7285de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach        return Error(L, "unexpected token in .thumb_func directive");
7286de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Name = Tok.getIdentifier();
7287de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Parser.Lex(); // Consume the identifier token.
7288de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      needFuncName = false;
7289de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    }
72906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
72916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7292de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
7293515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7294de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach
7295de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Eat the end of statement and any blank lines that follow.
7296de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  while (getLexer().is(AsmToken::EndOfStatement))
7297de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    Parser.Lex();
7298515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
72996469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
7300de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // We really should be checking the next symbol definition even if there's
7301de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // stuff in between.
7302de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (needFuncName) {
7303d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
73046469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
73056469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7306642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
7307642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
7308642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
7309515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7310515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7311515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73121355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
7313515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
73141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
731518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7316515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
7317515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
731838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
731958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
7320b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
732158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
73229e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
7323515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7324515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
7325515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7326515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
732718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7328b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7329515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7330515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
7331515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
7332515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7333515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7334515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
7336515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
73371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
733818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7339515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
7340515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
734118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
734258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
7343b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
734458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
7345b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
7346515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7347515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
7348515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7349515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
735018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7351b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7352515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
735332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
735498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
7355ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
735698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
735732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
735898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
7359ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
736098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7361eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
73622a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
7363515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7364515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7365515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7366a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
7367a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
7368a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7369a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
7370a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
7371a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
7372a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
7373a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7374a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
7375a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7376a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7377a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
7378a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7379a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7380a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
7381a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
7382a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7383a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7384a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
7385a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7386a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
7387a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
7388a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
7389a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7390a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7391a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7392a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7393a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
7394a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
7395a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
7396a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
7397a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7398a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
7399a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7400a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
7401a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
7402a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7403a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7404a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7405d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch
7406d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .arch token
7407d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) {
7408d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7409d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7410d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
7411d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr
7412d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .eabi_attribute int, int
7413d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
7414d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7415d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7416d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
741790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
741890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
74199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
7420ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
742194b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
742294b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
742390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
7424ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
74253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
74260692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
74270692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
74283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
7429