ARMAsmParser.cpp revision 3a86e1396230748f17a521915bc802939a787eac
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;
4728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  const MCRegisterInfo *MRI;
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
49a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Map of register aliases registers via the .req directive.
50a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StringMap<unsigned> RegisterReqs;
51a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
68f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
69f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
70f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
71f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
76a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
77a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
78a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
79a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
80f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
81f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
84ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
85362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  bool Warning(SMLoc L, const Twine &Msg,
86362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer               ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
87362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer    return Parser.Warning(L, Msg, Ranges);
88362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  }
89362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  bool Error(SMLoc L, const Twine &Msg,
90362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer             ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
91362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer    return Parser.Error(L, Msg, Ranges);
92362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  }
93ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
960d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
1017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
1027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
1031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
1041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
1059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
1061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
1071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
109a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveReq(StringRef Name, SMLoc L);
110a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveUnreq(SMLoc L);
111d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveArch(SMLoc L);
112d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveEabiAttr(SMLoc L);
113515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
11589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
11689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
118fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
120ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
121ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
122ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
123ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
124ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
125ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
126ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
12747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
12847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
130194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
131194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
132194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
133acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
134acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
135acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
13632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
137ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
138ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
140acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
141acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
142acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
143ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1470692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1480692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
149a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
15343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
154f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
156f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1608bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
16143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1628bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
16343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1648bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
166f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
167f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
168f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
169f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
170f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
171f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
172f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
173c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
174580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
176293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
178251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1799d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
180862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
182ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
183ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
184756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtT2LdrdPre(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &);
185756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtT2StrdPre(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &);
186756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst,
187eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
188756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst,
189ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
190756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdWriteBackRegAddrMode2(MCInst &Inst,
191ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
192756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdWriteBackRegAddrModeImm12(MCInst &Inst,
1939ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
194756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStWriteBackRegAddrModeImm12(MCInst &Inst,
195548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
196756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStWriteBackRegAddrMode2(MCInst &Inst,
197ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
198756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStWriteBackRegAddrMode3(MCInst &Inst,
1997b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
200756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdExtTWriteBackImm(MCInst &Inst,
2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
202756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdExtTWriteBackReg(MCInst &Inst,
2037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
204756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStExtTWriteBackImm(MCInst &Inst,
2057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
206756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStExtTWriteBackReg(MCInst &Inst,
2077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
208756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdrdPre(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &);
209756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtStrdPre(MCInst &Inst, const SmallVectorImpl<MCParsedAsmOperand*> &);
210756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtLdWriteBackRegAddrMode3(MCInst &Inst,
211623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
212756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtThumbMultiply(MCInst &Inst,
21388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
214756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtVLDwbFixed(MCInst &Inst,
21512431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
216756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtVLDwbRegister(MCInst &Inst,
21712431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
218756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtVSTwbFixed(MCInst &Inst,
2194334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
220756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad Rosier  void cvtVSTwbRegister(MCInst &Inst,
2214334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
222189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
223189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
225f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
226d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
227d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
228189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
229ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
23047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
231194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
232f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
233194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
23470c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    Match_RequiresThumb2,
23570c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach#define GET_OPERAND_DIAGNOSTIC_TYPES
23670c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach#include "ARMGenAsmMatcher.inc"
23770c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach
23847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
23947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
240ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
24194b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
242ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
24332869205052430f45d598fba25ab878d8b29da2dEvan Cheng
24428f08c93e75d291695ea89b9004145103292e85bJim Grosbach    // Cache the MCRegisterInfo.
24528f08c93e75d291695ea89b9004145103292e85bJim Grosbach    MRI = &getContext().getRegisterInfo();
24628f08c93e75d291695ea89b9004145103292e85bJim Grosbach
247ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
248ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
249f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
252ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
253ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
257189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
26047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
26147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
265ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
26616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
26716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2683a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
270a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
271a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
272146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
27821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
28421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
286460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
28721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
28821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
28921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
291862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
29298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2937636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
29421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
29521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
29621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
29721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
29821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
29921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
30324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
3078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
3088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
311fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
312fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
313fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
314fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
31989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
32089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
32189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
32289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
32389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
32489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
32589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
32689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
331584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
332584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
333584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
334584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
337a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
338a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
339a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
340a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
341a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
342a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
343862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
344862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
345862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
346862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3480aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
349862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
350862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3518155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
352460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
353460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
354460a90540b045c102012da2492999557e6840526Jim Grosbach
355460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
356cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
357cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
35816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3596a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
360a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
361a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
36757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
36857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
369eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
371e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
375f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
376f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
377f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
381580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
383580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
385e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
386e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
387e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
388e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
389af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
39092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
39192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
39292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
39392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
394af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
398293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
399293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
400293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
401293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
402a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
40316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
404146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
405146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
406762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
407762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
408762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
409762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
410762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
41121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
41589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
41689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4188462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
419762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
422762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
423762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
42521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
42724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
429862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
43098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
432862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
433862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
43421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
43521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
436fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
437fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
44121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
443762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
445706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
446706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
44721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
448e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
449762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
45021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
45321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
454584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
455584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
45621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
457a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
46221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
463af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
464e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
46521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
466af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
46792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
47121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
472293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
473293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
474460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
475460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
476460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
480762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
481762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
482762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
483762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
485362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
486362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer
4878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
492fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
494fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
495fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
496fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
500a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
502a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
5047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5075fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
50821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
50921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
51024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5118d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
513cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
51421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    assert(isImm() && "Invalid access!");
515cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
516cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
517cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
518460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
519460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
520460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
521460a90540b045c102012da2492999557e6840526Jim Grosbach  }
522460a90540b045c102012da2492999557e6840526Jim Grosbach
523706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
525706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
526706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
527706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
528a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
530a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
532a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
533584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
535584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
536584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
537584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
53821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
54121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
54221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
54421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
54521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
54651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  bool isFPImm() const {
54751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!isImm()) return false;
54851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
54951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!CE) return false;
55051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
55151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    return Val != -1;
55251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  }
5534050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits16() const {
5544050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5554050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5564050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5574050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5584050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 0 && Value <= 16;
5594050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
5604050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits32() const {
5614050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5624050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5634050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5644050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5654050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 1 && Value <= 32;
5664050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
567a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
56821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
569a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
570a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
571a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
572a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
573a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
57472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
57521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57672f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57772f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57872f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
57972f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
58072f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
58172f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
58221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
58372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
58472f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
58572f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
58672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
58772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5884e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  bool isImm0_508s4Neg() const {
5894e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!isImm()) return false;
5904e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5914e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!CE) return false;
5924e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    int64_t Value = -CE->getValue();
5934e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // explicitly exclude zero. we want that to use the normal 0_508 version.
5944e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    return ((Value & 3) == 0) && Value > 0 && Value <= 508;
5954e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
5966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
59721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
5986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
6006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
6016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
6026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6034e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  bool isImm0_4095() const {
6044e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!isImm()) return false;
6054e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6064e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!CE) return false;
6074e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    int64_t Value = CE->getValue();
6084e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    return Value >= 0 && Value < 4096;
6094e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
6104e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  bool isImm0_4095Neg() const {
6114e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!isImm()) return false;
6124e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6134e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!CE) return false;
6144e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    int64_t Value = -CE->getValue();
6154e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    return Value > 0 && Value < 4096;
6164e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
617587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
61821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
619587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
620587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
621587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
622587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
623587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
624587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
62521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
626587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
627587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
628587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
629587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
630587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
63183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
63221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
63383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
63483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
63583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
63683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
63783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
63883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
63921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
64083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
64183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
64283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
64383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
64483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6457c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
64621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6477c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6487c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6497c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6507c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6517c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
652730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
65321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
654730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
655730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
656730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
657730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
658730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6593b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
66021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6613b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6623b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6633b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6643b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6653b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6663b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
66721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6683b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6693b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6703b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6713b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6723b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6733b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
67421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6753b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6763b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6773b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6793b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6806b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
68121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6826b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6836b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6846b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6856b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6866b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6876b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
68821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6896b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6906b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6916b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6926b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6936b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6946b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
69521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6966b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6976b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6986b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6996b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
7006b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
7016b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
70221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7036b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7046b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
7056b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
7066b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
7076b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
7083b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
70921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7103b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7113b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7123b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7133b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
7143b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
7153b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
71621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7173b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7183b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7193b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7203b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
7213b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
7223b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
72321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7243b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7253b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7263b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
7283b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
729f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
73021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
731f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
732f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
733f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
734f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
735f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7364a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
73721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7384a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7394a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7404a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7414a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7424a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
743ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
74421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
745ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
746ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
747ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
748ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
749ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
750fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
75121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
752fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
753fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
754fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
755fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
756fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
757ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
75821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
759ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
760ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
761ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
762ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
763ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
764ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
765ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
766ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
76721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
768ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
769ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
770ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
771ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
772ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
77370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
77421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
77570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
77670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
77770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
77870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
77970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
780f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
78121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
782f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
783f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
784f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
785f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
786f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
787f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
78821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
789f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
790f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
791f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
792f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
793f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7941fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  bool isAdrLabel() const {
7951fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // If we have an immediate that's not a constant, treat it as a label
7961fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // reference needing a fixup. If it is a constant, but it can't fit
7971fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // into shift immediate encoding, we reject it.
7981fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    if (isImm() && !isa<MCConstantExpr>(getImm())) return true;
7991fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    else return (isARMSOImm() || isARMSOImmNeg());
8001fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  }
8016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
80221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8046bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
8056bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
8066bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
8076bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
808e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
80921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
810e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
811e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
812e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
813e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
814e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
8153bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
81621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8173bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8183bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8193bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
820ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    // Only use this when not representable as a plain so_imm.
821ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    return ARM_AM::getSOImmVal(Value) == -1 &&
822ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach      ARM_AM::getSOImmVal(-Value) != -1;
8233bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
8246b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
82521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8266b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8276b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
8286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
8296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
8306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
83189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
83221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
83389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
83489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
83589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
83689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
83789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
8383bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
83921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8403bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8413bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8423bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
843ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    // Only use this when not representable as a plain so_imm.
844ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    return ARM_AM::getT2SOImmVal(Value) == -1 &&
845ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach      ARM_AM::getT2SOImmVal(-Value) != -1;
8463bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
847c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
84821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
849c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
850c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
851c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
852c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
853c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
85421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
85521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
85621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
85721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
85821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
85921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
86021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
86121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
86221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
86321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
86421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
86521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
86621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
867f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
868430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
869f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
87057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
871f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
872ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
87457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
87557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
87657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
8770b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  bool isMemPCRelImm12() const {
8780b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
8790b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8800b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base register must be PC.
8810b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum != ARM::PC)
8820b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8830b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Immediate offset in range [-4095, 4095].
8840b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!Memory.OffsetImm) return true;
8850b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8860b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8870b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
88857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
88957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
890ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
89257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
894e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
896e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
897e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
900039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
90121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
902039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
903039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
904039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
905039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
906039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
907039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
9082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
9092f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
9102f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
9112f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
91221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
9132f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
91457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
916e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
9172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
918e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
9192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
920e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
921e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
922ca3cd419a52c1dedee133d79772ef97f30e5d20bSilviu Baranga    // The #-0 offset is encoded as INT32_MIN, and we have to check
923ca3cd419a52c1dedee133d79772ef97f30e5d20bSilviu Baranga    // for this too.
924ca3cd419a52c1dedee133d79772ef97f30e5d20bSilviu Baranga    return (Val > -256 && Val < 256) || Val == INT32_MIN;
9252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
9262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
92721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
9282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
92921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
9302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
9312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
9322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
9342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
935251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
936251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
9372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
939681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
940681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
941681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
94221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
943681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
94457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
946e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
948e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
949e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9500da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
951681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
954e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
95557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9567f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9577f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9587f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9597f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
960e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
96157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
96257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9637f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9647f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9657f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
96757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
968ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
969ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
970ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
971ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
97257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
97357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
974ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
975ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
976e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
977ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
978e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
979ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
980ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
981ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
98657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
98787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
988e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
989e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
99060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
99160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
992e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
99357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
99460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
99560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
996e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
997e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
998ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
999ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
100038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
1001e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
100257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
100338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
100438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
1005e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1006e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
100738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
100838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
100948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
1010e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
101157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
101248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
101348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
1014e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1015e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
101648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
101748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
1018ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
101957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
102057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
1021ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
1022ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
1023e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1024e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1025ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1026505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1027a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
10282f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
10292f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
10302f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
103121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
10322f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
103357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1034a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
1035a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
1036e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1037e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1038fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    // Special case, #-0 is INT32_MIN.
1039fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN;
1040a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1041b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
104257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1043b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
1044b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
1045e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1046e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1047b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1048b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
105057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1051f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10520b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10530b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
10547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1055e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1056e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10574d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1058f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1059f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
106057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1061f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1062f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1063e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1064e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1065f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1066f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1067a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
106857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1069a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
10700b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10710b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
1072a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1073df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1074e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1075df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1076a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1077a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
107857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1079a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1080a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1081e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1082e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1083a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1084a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
108609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
108709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
108809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
108921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
109009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
109109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
109257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1093ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1095e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1096e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10970da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
110021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
11017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1102ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
11037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
110463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1105ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
11062bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
110721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
11082bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11092bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
11102bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
11112bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
11122bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
11132bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
11147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
111521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
111621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
11173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
11190aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
11200aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
11210aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
11220aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
11230aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
11240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1125862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
11260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1127862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1128862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1129862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
113028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  bool isVecListDPair() const {
113128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!isSingleSpacedVectorList()) return false;
113228f08c93e75d291695ea89b9004145103292e85bJim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
113328f08c93e75d291695ea89b9004145103292e85bJim Grosbach              .contains(VectorList.RegNum));
113428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
113528f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1136cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
11370aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1138cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1139cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1140cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1141b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
11420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1143b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1144b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1145b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
1146c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  bool isVecListDPairSpaced() const {
11479f2e160f7ae90a7a80b17e38ad06f2c706515115Kevin Enderby    if (isSingleSpacedVectorList()) return false;
1148c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1149c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach              .contains(VectorList.RegNum));
1150c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  }
1151c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1152c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  bool isVecListThreeQ() const {
1153c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
1154c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return VectorList.Count == 3;
1155c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
1156c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
11577945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  bool isVecListFourQ() const {
11587945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11597945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    return VectorList.Count == 4;
11607945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  }
11617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
11623471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isSingleSpacedVectorAllLanes() const {
11633471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
11643471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11653471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isDoubleSpacedVectorAllLanes() const {
11663471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
11673471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
116898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
11693471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
117098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
117198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
117298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
1173c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  bool isVecListDPairAllLanes() const {
11743471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1175c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1176c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach              .contains(VectorList.RegNum));
11773471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11783471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach
11794d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  bool isVecListDPairSpacedAllLanes() const {
11803471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
118113af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
118213af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
118313af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11845e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeDAllLanes() const {
11855e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11865e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11875e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11885e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
11895e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeQAllLanes() const {
11905e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
11915e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11925e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11935e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
1194a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourDAllLanes() const {
1195a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1196a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1197a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1198a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
1199a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourQAllLanes() const {
1200a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
1201a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1202a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1203a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
120495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isSingleSpacedVectorIndexed() const {
120595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
120695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
120795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isDoubleSpacedVectorIndexed() const {
120895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
120995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
12107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
121195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
12137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
12147636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1215799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
121695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1217799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1218799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1219799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1220799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
122195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1222799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1223799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1224799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
122695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
12289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
12299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1230799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
123195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
123295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
123395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
123495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
123595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQWordIndexed() const {
123695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
123795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
123895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
123995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
124095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQHWordIndexed() const {
124195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1242799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1243799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1244799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1245799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
124695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1247799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1248799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1249799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDByteIndexed() const {
12513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
12533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDHWordIndexed() const {
12563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQWordIndexed() const {
12613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQHWordIndexed() const {
12663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12683a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDWordIndexed() const {
12713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
1275e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDByteIndexed() const {
1276e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1277e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1278e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1279e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1280e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDHWordIndexed() const {
1281e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1282e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1283e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1284e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1285e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQWordIndexed() const {
1286e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1287e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1288e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1289e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1290e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQHWordIndexed() const {
1291e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1292e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1293e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1294e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1295e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDWordIndexed() const {
1296e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1297e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1298e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1299e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1300460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1301460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1302460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1303460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1304460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1305460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1306460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1307460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1308460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1309460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1310460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1311460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1312460a90540b045c102012da2492999557e6840526Jim Grosbach
13130e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
131421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13150e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
13170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
13180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
13190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
13200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
13210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
13220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1323460a90540b045c102012da2492999557e6840526Jim Grosbach
1324ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
132521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1326ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1327ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1328ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1329ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1330ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1331ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1332ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1333ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
13346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
133521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
13416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
13456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
13476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
134821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13629b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  bool isNEONi32vmovNeg() const {
136321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13649b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13659b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // Must be a constant.
13669b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (!CE) return false;
13679b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    int64_t Value = ~CE->getValue();
13689b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13699b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13709b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    return (Value >= 0 && Value < 256) ||
13719b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13729b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13739b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13749b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13759b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13769b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
13776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1378f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
137921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1380f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1381f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1382f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1383f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1384f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1385f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1386f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1387f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1388f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1389f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
13903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
139114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
139214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
139314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
139414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
13953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
13963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
13973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
13983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
13993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1401345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
14028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
140304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
140404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
14058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
14068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1407fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1408fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1409fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
14129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
14139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
14159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
14169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
14179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
14189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
14209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
14219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
142289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
142389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
142489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
142589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
142689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
142789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
142889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
142989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
143089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
143189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1432d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1433d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1434d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1435d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1436d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1437a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1438a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1440a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1442af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1443e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1444430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1445430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1446af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1447af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1448e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1449af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1450e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1451e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1452af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1453152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1454430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1455430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1456af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
1457b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    // Shift of #32 is encoded as 0 where permitted
1458b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
145992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1460b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
146192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
146292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
14640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1466580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
14670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
146987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
14707729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
14715fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
14725fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
14737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
14747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
147587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
147687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
14770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
14780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
14820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
14867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
14887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
14897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1491293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1492293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1493293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1494293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1495293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1496293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1497293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1498293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1499293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1500293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1501293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
15023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
15036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
15056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
15066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
15074050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits16Operands(MCInst &Inst, unsigned N) const {
15084050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15094050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15104050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
15114050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
15124050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
15134050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits32Operands(MCInst &Inst, unsigned N) const {
15144050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15154050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15164050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
15174050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
15184050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
15199d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
15209d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
152151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
152251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
152351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15249d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
15259d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1526a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1527a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1528a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1529a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1530a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1531a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1532a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1533a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
153472f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
153572f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
153672f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
153772f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
153872f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
153972f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
154072f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
154172f39f8436848885176943b0ba985a7171145423Jim Grosbach
15424e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
15434e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15444e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // The immediate is scaled by four in the encoding and is stored
15454e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // in the MCInst as such. Lop off the low two bits here.
15464e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15474e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-(CE->getValue() / 4)));
15484e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
15494e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach
155072f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
155172f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
155272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
155372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
155472f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
155572f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
155672f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
155772f39f8436848885176943b0ba985a7171145423Jim Grosbach
1558f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1559f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1560f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1561f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1562f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1563f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1564f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1565f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
15664a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
15674a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15684a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
15694a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
15704a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
15724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
15734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
157470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
157570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
157670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
157770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
157870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
157970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
158070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1581ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1582ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1583f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1584f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1585f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1586f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1587f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1588f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1589f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1590f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1591f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
159289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
159389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
159489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
159589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
159689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
159789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
159889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
159989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
16003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
16013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
16033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
16043bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
16063bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
16073bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
16084e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
16094e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16104e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // The operand is actually an imm0_4095, but we have its
16114e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // negation in the assembly source, so twiddle it here.
16124e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16134e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
16144e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
16154e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach
1616e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1617e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1618e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1619e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1620e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1621e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1622e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1623e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
16243bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
16253bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16263bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
16273bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
16283bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16293bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
16303bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
16313bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1632706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1633706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1634706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1635706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1636706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
16377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
16387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1639e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1640505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1641505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
16420b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
16430b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16440b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int32_t Imm = Memory.OffsetImm->getValue();
16450b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // FIXME: Handle #-0
16460b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
16470b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
16480b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
16490b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach
16501fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
16511fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    assert(N == 1 && "Invalid number of operands!");
16521fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    assert(isImm() && "Not an immediate!");
16531fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
16541fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // If we have an immediate that's not a constant, treat it as a label
16551fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // reference needing a fixup.
16561fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    if (!isa<MCConstantExpr>(getImm())) {
16571fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu      Inst.addOperand(MCOperand::CreateExpr(getImm()));
16581fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu      return;
16591fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    }
16601fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
16611fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16621fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    int Val = CE->getValue();
16631fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    Inst.addOperand(MCOperand::CreateImm(Val));
16641fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  }
16651fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
166657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
166757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
166857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
166957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
167057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
167157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
16727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
16737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1674e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1675e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
16787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
16807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
16817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
16827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
16837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1684e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1685e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1686ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1687e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1688e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1690ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1691ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1692039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1693039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1694039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1695039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1696039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1697039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1698039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1699039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1700039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1701039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1702039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1703039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1704039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1705039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
17062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
17072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
17082f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
17092f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
17102f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
17112f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
17122f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
17132f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
17142f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
17152f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17162f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17172f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1718e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1719e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
17202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
17212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
17222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
17232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
17242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
17252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
17262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
17272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1728e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
17292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1730e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1731e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
17342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
17352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
17362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
173721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
17382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
17392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
17402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
17412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1742251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
17432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
17442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
17452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
17462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
17472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
17482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
17492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
17502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
17512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1752251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
17532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
17542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
17562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
17577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
17587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1759681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1760681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1761681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1762681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1763681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1764681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1765681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1766681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1767681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
17687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1769e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
17707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
17717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
17727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
17737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
17747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1775e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
17787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1779a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1780a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
17812f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
17822f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
17832f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
17842f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
17852f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
17862f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
17872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17882f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1790e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1791e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1792a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1793a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1794a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1795b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1796b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1797b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1798e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1799e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1800b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1801b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1802b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
18037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
18047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1805e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1806e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
18077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1808ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1809ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1810f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1811f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1812f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1813f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1814a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1815f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1816a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1817a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1818a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1819a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1820a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
182121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
1822a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1823a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1824a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1825a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1826a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1827a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1828e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1829e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1830a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1831a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1832a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
18337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
18347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
183509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
183621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
183709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
183809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
183909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
184009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
184109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
184209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1843e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1844e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
18457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
18467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
184792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
18487f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
18497f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1850e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1851e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
18527f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
18537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
18547f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
18557f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1856e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1857e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
18587f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
18597f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
18607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
18617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1862430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1863430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1864430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1865e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1866e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
18677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
18687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1869d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1870ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1871ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1872e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1873e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1874e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1875ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1876ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
18777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
18787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1880e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
188114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
18823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
188360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
188460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1885e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1886e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
188760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
188848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
188948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
189038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
189138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1892e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1893e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
189438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
189538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
189638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
189748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
189848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1899e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1900e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
190148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
190260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
190360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1904ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1905ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1906e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1907e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1908ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1909ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1910ecd858968384be029574d845eb098d357049e02eJim Grosbach
19117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
19127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
19157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
19167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
191763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
19187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
19197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1920f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1921ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
19222bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
19232bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
19242bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19252bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
19262bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
19272bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
19282bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
19292bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
19302bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
19312bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
19322bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
19332bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
19347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
19357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
19367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1937f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1938f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1939f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1940f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1941f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1942f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1943f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1944f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1945f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1946f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1947f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1948f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1949ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1950ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1951584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1952584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1953584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1954584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1955584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1956a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1957a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1958a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1959a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1960a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
19616029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1962862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1963862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1964862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1965862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
19667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
19677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
19687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
19697636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
19707636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
19717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1972460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1973460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1974460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1975460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1976460a90540b045c102012da2492999557e6840526Jim Grosbach
1977460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1978460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1979460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1980460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1981460a90540b045c102012da2492999557e6840526Jim Grosbach
1982460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1983460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1984460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1985460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1986460a90540b045c102012da2492999557e6840526Jim Grosbach
19870e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
19880e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19890e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19900e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
19910e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19920e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
19930e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
19940e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1995ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1996ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1997ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1998ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1999ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
2000ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
2001ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
2002ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
2003ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
2004ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
2005ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
2006ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
20076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
20086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
20096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
20106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
20126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
20136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
20146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
20156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
20166248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
20176248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
20186248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
20196248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
20206248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
20216248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
20226248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
20236248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
20246248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20256248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
20266248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
20276248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
20286248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
20296248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
20306248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
20316248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
20329b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
20339b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
20349b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach
20359b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
20369b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
20379b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // The immediate encodes the type of constant as well as the value.
20389b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20399b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    unsigned Value = ~CE->getValue();
20409b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
20419b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
20429b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
20439b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
20449b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffffff)
20459b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 24) | 0x600;
20466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
20476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
20486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
2049f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
2050f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
2051f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
2052f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2053f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
2054f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
2055f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
2056f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
2057f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
2058f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
2059f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
2060f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
2061b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
2062b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
206389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
206421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
206589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
206689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
206789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
206889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
206989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
207089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
20713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
207221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
2073345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
2074345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
2075345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
20763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2077345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
2078345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2079fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
208021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
2081fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2082fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2083fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2084fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2085fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2086fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2087fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
208821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
2089fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2090fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2091fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2092fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2093fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2094fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
20959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
20969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
20979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
20989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
20999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
21009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
21019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
21029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2103d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
210421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
2105d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
2106d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
2107d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
2108d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
2109d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
2110d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
21113a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
211221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
2113762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
2114762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
2115762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
21173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2119a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
212050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
212121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
2122762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
2123762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2124762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2128e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
2129e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
2130e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
2131e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
2132e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
213321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
2134af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
2135af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
2136af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
2137af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
2138e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
2139e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
2140e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
2141e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2142e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
214392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
214492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
214592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
214692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
214721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
2148af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
2149af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
2150af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
215192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
215292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
215392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
215492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
215592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
2156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
21570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
215821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
2159580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
2160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
21610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
21620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
21630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
21640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
21650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
21667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
216721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
21687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
21697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
21707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
21717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
21727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2174293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
2175293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
217621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
2177293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
2178293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
2179293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
2180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
2181293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
2182293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2183293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
21847729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
21855fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
2186cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
218721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
21880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
2189d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
219021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
2191d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2192275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
219321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
21940f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
21950f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
21965fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
21977729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
219824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
2199cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
2200cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
2201cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
22028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
22038d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
22048d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
2205862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
22060aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
2207862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
2208862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
2209862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
22100aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2211862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
2212862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
2213862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
2214862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2215862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
221698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
22173471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                              bool isDoubleSpaced,
221898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
221998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
222098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
222198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
22223471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
222398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
222498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
222598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
222698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
222798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
22287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
222995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             unsigned Index,
223095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             bool isDoubleSpaced,
223195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             SMLoc S, SMLoc E) {
22327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
22337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
22347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
22357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
223695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
22377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
22387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
22397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
22407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
22417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
2242460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
2243460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
2244460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
2245460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
2246460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
2247460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
2248460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
2249460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2250460a90540b045c102012da2492999557e6840526Jim Grosbach
22513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
225221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
2253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
2254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2257cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2258cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
22597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
22607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
22617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
22627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
22630d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
226457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
22657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
22663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
226721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2268e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2269e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2270e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2271e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2272e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
227357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2274e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
22757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
22767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
22777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
22787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
227916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2280f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2281f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2282f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
22837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
228421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
22857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2286f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2287f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2288f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2293706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2294706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
229521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2296706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2297706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2298706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2300706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2302a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
230321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2304a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2305a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2306a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2307a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2308a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
231121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2321b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2322fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
232321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
23246a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2325fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
232621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2327d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2328d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
232921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
2330032f441afcdd70eb6bda477d32e8c372443b4e6fCraig Topper    static const char *const MaskStr[] = {
23311a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
23321a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
23331a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
233489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
233589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
233689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
233789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
233821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2339fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2340fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
234121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2342fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2343fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
23449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
23459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
23469b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
234721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2349584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
235021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2351fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2352fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
235321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2354706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2355706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
235621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
23576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2358e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
23596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2360fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
236121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2362f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2363f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2364f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2365f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2366f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2367f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
23687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
236921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2370a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2371a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2372a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2373a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2374a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2375a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2376a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2377a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
237821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
237950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2380fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
238121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2382580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2383580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
238521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
238692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2387efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2388efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2389efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
23900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
239121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
239292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2393efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2394efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2395efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
239692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
239721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
23987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
23997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
240021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2401293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2402293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2403293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
240421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
240521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
240621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
24078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
24088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
24095fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
24105fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
24117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
24127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
24137729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
24148d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
24158d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
24168d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
24178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
24188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2419862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2420862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2421862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2422862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
242398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
242498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
242598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
242698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
24277636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
24287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
24297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
24307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
243121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2432fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2433fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2434460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2435460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2436460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2437fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2438fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
24393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
24403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
24413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
24423483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
24433483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
24443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
24453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
24463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
244769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
244869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2449a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
24501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2451a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2452bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2453bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2454bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2455bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
24569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2457e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2458e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
24593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
24601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
246118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
24627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2463d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2464590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
24650c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
24660c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
24670c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
24680c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
24690c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
24700c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
24710c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
247240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
247340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
247440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
247540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
247640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
247740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
247840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
247940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
248040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
248140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
248240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
248340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
248440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
248540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
248640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
248740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
24880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
24890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2490a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2491aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // Check for aliases registered via .req. Canonicalize to lower case.
2492aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // That's more consistent since register names are case insensitive, and
2493aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // it's how the original entry was passed in from MC/MCParser/AsmParser.
2494aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
2495a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2496a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2497a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2498a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2499a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2500a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
250169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2502b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2503460a90540b045c102012da2492999557e6840526Jim Grosbach
2504e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2505e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2506d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
250719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
250819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
250919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
251019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
251119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
25120d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
25130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
25140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
25150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
25160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
25170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2518590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
25190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2520af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
25210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
25220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
25230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
25240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
25250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
25260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
25270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
25280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
252919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
25300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2531e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2532e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2533e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2534e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2535e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2536eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2537e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2538e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2539e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2540e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2541e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2542e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2543e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2544e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2545e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2546e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2547e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2548e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
25498a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
25508a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2551e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2552e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2553e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
255419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
255519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
255619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
255719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2558e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2559e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
256019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
256119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
256219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
256319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2564e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2565e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2566e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2567e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2568e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2569e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2570e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
257119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
257219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2573e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2574de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // shift by zero is a nop. Always send it through as lsl.
2575de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // ('as' compatibility)
2576de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      if (Imm == 0)
2577de626ad8726677328e10dbdc15011254214437d7Jim Grosbach        ShiftTy = ARM_AM::lsl;
2578e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
25791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2580e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
258119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
258219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
258319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
258419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
258519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
258619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2587e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
258819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
258919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2590e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2591e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
259292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
259392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2594af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
25950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
259692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
259792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
259892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
25990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
260019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
26010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
26020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
26030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
260450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
260550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
260650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2607e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2608e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2609e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
261050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
26111355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2612e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
26131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2614e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
261550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2616d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
261750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2619e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2620e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
262150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
262250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2623e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2624460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2625460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2626460a90540b045c102012da2492999557e6840526Jim Grosbach
2627460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2628460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2629460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2630460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2631460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2632460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2633460a90540b045c102012da2492999557e6840526Jim Grosbach
2634460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2635460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
263624dda217052b48373ed89d043a778aabb2f65080Jim Grosbach      return true;
2637460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2638ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (!MCE)
2639ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return TokError("immediate value expected for vector index");
2640460a90540b045c102012da2492999557e6840526Jim Grosbach
2641460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2642ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
2643ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return Error(E, "']' expected");
2644460a90540b045c102012da2492999557e6840526Jim Grosbach
2645460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2646460a90540b045c102012da2492999557e6840526Jim Grosbach
2647460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2648460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2649460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
265099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
265199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
265250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2655fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2656fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2657fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2658fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2659e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2660e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2661e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
26624d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default: return -1;
2663e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2664fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2665e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2666e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2667e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2668e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2669e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2670e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2671e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2672e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2673e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2674e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2675e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2676e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2677e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2678e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2679e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2680fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2681e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2682e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2683e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2684e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2685e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2686e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2687e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2688e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2689e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2690e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2691e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2692e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2693e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
269489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
269589df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
269689df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
269789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
269889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
269989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
270089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
270104a09a461beb4ec629fe53e601b7665547ac35c3Richard Barton  unsigned CC = StringSwitch<unsigned>(Tok.getString().lower())
270289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
270389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
270489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
270589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
270689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
270789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
270889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
270989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
271089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
271189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
271289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
271389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
271489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
271589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
271689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
271789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
271889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
271989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
272089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
272189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
272289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
272389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
272489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
272589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
272689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
272789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
272889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
272943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2732f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
273343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2734e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2735e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2736c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2737c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2738e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2740e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2741f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2742e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2743e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2744fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2745f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2746fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2747fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
274843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2749fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2750fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2751f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
275243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2753fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2754fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2755c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2756c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2757fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2758fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2759fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2760f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2761fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2762fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2763fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2764f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2765e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2766e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
27679b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
27689b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
27699b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
27709b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
27719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
27729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
27749b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
27759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
27769b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
27779b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27789b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
27799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
27809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
27819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
27829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27839b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
27859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
27869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
27879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
27909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
27929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
27939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
27959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
27969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
27989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
27999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
28009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2801d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2802d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2803d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2804d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2805d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2806d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2807d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2808d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2811bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid GPR number!");
2812d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2813d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2814d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2815d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2816d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2817d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2818d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2819d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2820d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2821d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2822d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2823ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2824ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2825ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2826ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2827ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2828ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2829ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2830ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2831ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2832ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2833ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2834ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2835ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
283625e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2837ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2838ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2839ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2840ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2841ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2842ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2843ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2844ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2845ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2846d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
284750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
28481355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
284918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2850a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2851e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2852d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2853d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
285416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2855d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2856d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2857d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2858d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2859d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2860d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2861ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2862ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2863ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2864ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2865ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2866ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2867ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2868ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2869ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2870ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
28711a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2872d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2873d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2874d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2875d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2876d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2877d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2878d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2879d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2880e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2881ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2882d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2883d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2884d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2885d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2886d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2887d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2888d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2889d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2890e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2891d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2892d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2893d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2894d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2895ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2896ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2897ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2898d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2899d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2900d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2901d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2902d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2903d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2904d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2905d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2906df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher      if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
2907d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2908d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2909d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2910d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2911d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2912d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2913d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2914d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2915d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2916d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2917d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2918d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2919a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2920d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2921d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
29222d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2923ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2924ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2925ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2926ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2927ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2928ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2929d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2930d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2931d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2932d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2933df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    if (MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) {
2934be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach      if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2935be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach        Warning(RegLoc, "register list not in ascending order");
2936be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach      else
2937be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach        return Error(RegLoc, "register list not in ascending order");
2938be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach    }
2939df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
2940a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2941a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2942a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2943a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2944d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2945d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2946d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2947d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2948d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2949d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2950d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2951ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2952ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2953d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2954d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2955d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2956d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2957d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2958d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2959e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
296027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
296150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
296227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
296327debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
296427debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
296527debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
296627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
296727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
296827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
296950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2970d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2971d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
297298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
297398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
29747636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
29757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
297698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
297798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
297898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
297998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
298098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
298198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
298298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
298398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2984ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach
2985ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach    // There's an optional '#' token here. Normally there wouldn't be, but
2986ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach    // inline assemble puts one in, and it's friendly to accept that.
2987ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash))
2988ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach      Parser.Lex(); // Eat the '#'
2989ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach
2990c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCExpr *LaneIndex;
2991c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    SMLoc Loc = Parser.getTok().getLoc();
2992c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (getParser().ParseExpression(LaneIndex)) {
2993c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "illegal expression");
2994c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
29957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
2996c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
2997c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (!CE) {
2998c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "lane index must be empty or an integer");
2999c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
3000c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
3001c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
3002c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "']' expected");
3003c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
3004c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
3005c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Parser.Lex(); // Eat the ']'.
3006c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    int64_t Val = CE->getValue();
3007c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach
3008c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    // FIXME: Make this range check context sensitive for .8, .16, .32.
3009c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Val < 0 || Val > 7) {
3010c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "lane index out of range");
3011c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
3012c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
3013c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Index = Val;
3014c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    LaneKind = IndexedLane;
3015c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    return MatchOperand_Success;
301698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
301798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
301898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
301998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
302098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
3021862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
3022862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3023862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
302498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
30257636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
30265c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
30275c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
30285c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
30295c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
30305c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
30315c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
30325c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
30335c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
30345c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
30355c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
30367636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
303798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
303898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
303998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
304098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
304198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
30420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
304398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
304498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
304598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
30463471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
30473471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
304898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
30497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
30507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
305195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
305295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
30537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
305498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
30555c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
30565c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
30575c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
30585c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
30597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
306098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
306198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
306298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
306398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
306498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
306528f08c93e75d291695ea89b9004145103292e85bJim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3066c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
30670aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
306898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
306998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
307098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
3071c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3072c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
30733471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
30743471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
307598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
30767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
30777636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
307895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
307995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
30807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
308198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
30825c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
30835c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
30845c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
30855c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
30865c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
30875c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
30885c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
3089862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
3090862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3091862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
3092862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
3093862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3094862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
3095862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
3096862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
3097862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3098862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3099862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
3100276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
3101c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
3102c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
3103c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
3104c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
3105c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
31060aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
31070aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
3108c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
3109c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
3110c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
31117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
311298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
3113c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
3114e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
3115e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
3116e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
31170aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
31180aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
31190aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
31200aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
31210aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
31220aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
31230aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3124e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
3125e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
3126e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
3127e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
3128e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
3129e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3130e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3131e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
3132e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
3133e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
3134e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
3135e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
3136e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
3137e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
3138e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
3139e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
3140e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
3141e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3142e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3143e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
3144e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
3145e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
3146e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3147e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
314898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
314998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
31507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
31517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
315298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
31537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
315498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
315598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
315698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
315798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
3158e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
3159e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
3160e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
3161e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
3162e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
3163e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
3164862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
3165862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
3166862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
3167862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
3168862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
3169862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
3170862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3171862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3172c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
3173862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
3174862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
3175c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
3176c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
3177c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
3178c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
31790aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
31800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
31810aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
31820aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
31830aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
31840aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
31850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3186c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
3187c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
3188c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
3189c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
3190c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
3191c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
3192c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
319398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
319498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
31957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
319698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
31977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
319898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
31997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
320098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
320198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
320298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
3203c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
3204c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
32050aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
32060aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
32070aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
32080aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
32090aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
32100aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
32110aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
32120aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
3213862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
3214862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3215862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3216862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
321798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
321898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
32197636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
322098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
32217636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
322298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
32237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
322498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
322598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
322698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
3227862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3228862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3229862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3230862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
3231862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
3232862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3233862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3234862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
3235862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
323698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
323798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
3238c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // Two-register operands have been converted to the
3239c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    // composite register classes.
3240c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (Count == 2) {
3241c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      const MCRegisterClass *RC = (Spacing == 1) ?
3242c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
3243c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3244c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3245c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    }
324628f08c93e75d291695ea89b9004145103292e85bJim Grosbach
32470aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
32480aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
324998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
325098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
3251c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // Two-register operands have been converted to the
3252c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // composite register classes.
32534d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    if (Count == 2) {
32544d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach      const MCRegisterClass *RC = (Spacing == 1) ?
32554d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
32564d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3257c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3258c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    }
325998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
32603471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                            (Spacing == 2),
326198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
326298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
32637636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
32647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
326595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           LaneIndex,
326695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           (Spacing == 2),
326795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           S, E));
32687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
326998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
3270862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
3271862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
3272862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
327343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
3274f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
327543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3276706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3277706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3278c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  unsigned Opt;
3279c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3280c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  if (Tok.is(AsmToken::Identifier)) {
3281c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    StringRef OptStr = Tok.getString();
3282c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3283c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower())
3284c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("sy",    ARM_MB::SY)
3285c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("st",    ARM_MB::ST)
3286c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("sh",    ARM_MB::ISH)
3287c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("ish",   ARM_MB::ISH)
3288c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("shst",  ARM_MB::ISHST)
3289c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("ishst", ARM_MB::ISHST)
3290c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("nsh",   ARM_MB::NSH)
3291c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("un",    ARM_MB::NSH)
3292c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("nshst", ARM_MB::NSHST)
3293c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("unst",  ARM_MB::NSHST)
3294c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("osh",   ARM_MB::OSH)
3295c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("oshst", ARM_MB::OSHST)
3296c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Default(~0U);
3297c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3298c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (Opt == ~0U)
3299c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_NoMatch;
3300706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3301c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    Parser.Lex(); // Eat identifier token.
3302c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  } else if (Tok.is(AsmToken::Hash) ||
3303c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu             Tok.is(AsmToken::Dollar) ||
3304c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu             Tok.is(AsmToken::Integer)) {
3305c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (Parser.getTok().isNot(AsmToken::Integer))
3306c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Parser.Lex(); // Eat the '#'.
3307c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    SMLoc Loc = Parser.getTok().getLoc();
3308c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3309c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    const MCExpr *MemBarrierID;
3310c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (getParser().ParseExpression(MemBarrierID)) {
3311c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Error(Loc, "illegal expression");
3312c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_ParseFail;
3313c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    }
3314c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3315c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
3316c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (!CE) {
3317c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Error(Loc, "constant expression expected");
3318c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_ParseFail;
3319c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    }
3320c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3321c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    int Val = CE->getValue();
3322c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (Val & ~0xf) {
3323c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Error(Loc, "immediate value out of range");
3324c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_ParseFail;
3325c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    }
3326c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3327c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    Opt = ARM_MB::RESERVED_0 + Val;
3328c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  } else
3329c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    return MatchOperand_ParseFail;
3330706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3331706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3332f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3333706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3334706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
333543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
333743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3340a1c7367a5bed459acc88e3ea2a482b4b5dac942aRichard Barton  if (!Tok.is(AsmToken::Identifier))
3341a1c7367a5bed459acc88e3ea2a482b4b5dac942aRichard Barton    return MatchOperand_NoMatch;
3342a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3343a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
33442dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
33452dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3346a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
33472dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
33482dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
33492dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
33502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
33512dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
33522dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
33532dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
33542dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
33552dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
33562dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
33572dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
33582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
33592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
33602dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
33612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3362a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3363a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3364a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3365a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3366a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3367584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3368584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
336943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3370584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
337143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3374584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3375584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3376584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3377acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3378acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3379b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    std::string Name = Mask.lower();
3380b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    unsigned FlagsVal = StringSwitch<unsigned>(Name)
33810fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // Note: in the documentation:
33820fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //  ARM deprecates using MSR APSR without a _<bits> qualifier as an alias
33830fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //  for MSR APSR_nzcvq.
33840fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // but we do make it an alias here.  This is so to get the "mask encoding"
33850fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // bits correct on MSR APSR writes.
33860fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //
33870fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // FIXME: Note the 0xc00 "mask encoding" bits version of the registers
33880fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // should really only be allowed when writing a special register.  Note
33890fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // they get dropped in the MRS instruction reading a special register as
33900fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // the SYSm field is only 8 bits.
33910fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //
33920fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // FIXME: the _g and _nzcvqg versions are only allowed if the processor
33930fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // includes the DSP extension but that is not checked.
33940fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr", 0x800)
33950fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr_nzcvq", 0x800)
33960fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr_g", 0x400)
33970fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr_nzcvqg", 0xc00)
33980fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr", 0x801)
33990fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr_nzcvq", 0x801)
34000fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr_g", 0x401)
34010fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr_nzcvqg", 0xc01)
34020fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr", 0x802)
34030fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr_nzcvq", 0x802)
34040fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr_g", 0x402)
34050fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr_nzcvqg", 0xc02)
34060fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr", 0x803)
34070fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr_nzcvq", 0x803)
34080fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr_g", 0x403)
34090fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr_nzcvqg", 0xc03)
3410f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("ipsr", 0x805)
3411f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("epsr", 0x806)
3412f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("iepsr", 0x807)
3413f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("msp", 0x808)
3414f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("psp", 0x809)
3415f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("primask", 0x810)
3416f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("basepri", 0x811)
3417f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("basepri_max", 0x812)
3418f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("faultmask", 0x813)
3419f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("control", 0x814)
3420acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
342118c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3422acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3423acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3424acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3425f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby    if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813)
3426acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3427acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
342818c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3429acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3430acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3431acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3432acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3433acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3434584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3435584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3436584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3437590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3438584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3439584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3440584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3441584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3442584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3443584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3444584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3445584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3448b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3449584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3450584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3451584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3452584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
34534b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3454584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3455584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3456584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3457bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
34584b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3459584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
3460b657a90929867716ca1c7c12d442bb5d32281bd4Jim Grosbach    // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
3461b657a90929867716ca1c7c12d442bb5d32281bd4Jim Grosbach    if (Flags == "all" || Flags == "")
346256926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3463584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3464584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3465584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3466584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3467584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3468584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3469584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3470584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3471584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3472584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3473584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3474584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3475584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3476584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3477584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3478584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3479584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
34807784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
34817784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
34827784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
34837784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
34847784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
34857784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
34867784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3487584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3488584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3489584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3490584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3491584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3492584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3493584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3494584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3495a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3496a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3497f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3498f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3499f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3500f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3501f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3502f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3503f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3504f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3505f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3506590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3507590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3508f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3509f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3510f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3511f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3512f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3513f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3514f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
35158a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35168a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3517f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3518f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3519f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3520f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3521f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3522f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3523f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3524f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3525f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3526f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3527f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3528f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3529f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3530f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3531f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3532f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3533f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3534f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3535f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3536f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3537f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3538f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3539f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3540f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3541f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3542f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3543f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3544c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3545c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3546c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3547c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3548c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3549c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3550c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3551c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3552c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3553c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3554c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3555c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3556c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3557c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3558c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3559c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3560c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3561c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3562c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3563c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3564c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3565c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3566c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3567c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3568580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3569580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3570580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3571580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3572580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3573580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3574580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3575580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3576580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3577580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3578580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3579580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3580580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3581580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3582580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3583580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3584580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3585580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3586580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3587580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3588580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3589580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3590580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3591580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3592580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3593580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
35948a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35958a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3596580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3597580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3598580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3599580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3600580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3601580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3602580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3603580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3604580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3605580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3606580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3607580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3608580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3609580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3610580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3611580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3612580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3613580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3614580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3615580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3616580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3617580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3618580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3619580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
36200afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
36210afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
36220afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
36230afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
36240afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3625580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3626580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3627580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3628580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3629580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3630580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3631580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3632580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3633580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3634580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3635580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3636580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3637580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3638580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3639580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
36407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
36417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
36427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
36437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
36447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
36467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3647326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3648326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
36497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3650326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3651326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
36527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
36537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
36558a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
36568a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
36577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
36587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
36617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
36637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
36647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
36657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
36667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
36697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
36707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
36717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
36757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
36767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
36777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
36787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
36797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
36807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
36847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
36857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
36877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
36887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3689293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3690293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3691293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3692293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
36938a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
36948a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3695293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3696293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3697293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3698293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3699293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3700293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3701293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3702293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3703293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3704293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3705293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3706293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3707293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3708293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3709293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3710293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3711293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3712293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3713293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3714293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3715293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3716293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3717293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3718293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3719293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3720293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3721293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3722293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3723293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3724293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3725293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
37268a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
37278a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3728293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3729293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3730293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3731293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3732293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3733293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3734293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3735293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3736293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3737293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3738293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3739293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3740293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3741293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3742293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3743293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3744293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3745293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3746293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3747293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3748293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3749293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3750293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3751293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3752293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3753293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3754293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3755293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3756293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
37577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
37587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3760f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3761f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3762f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
37637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
37647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
37657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
37667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
37677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
37687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
37697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
377016578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
37717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
37727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
37737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
37747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
37757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
37767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
377716578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
37787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
37797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
37807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
37817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
37827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
37837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
37847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
37857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
37867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
37877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
37887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
37897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3790f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3791f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
37920d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
37930d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
37940d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
37950d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
37960d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3797f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3798f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3799f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
38007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
38017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
38027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
38037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3804251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3805251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3806251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3807251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3808251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3809251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3810251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3811251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3812251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3813251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3814251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3815251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3816251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3817251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3818251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3819251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3820251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
38218a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
38228a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3823251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3824251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3825251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3826251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3827251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3828251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3829251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3830251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3831251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3832251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3833251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3834251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3835251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3836251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3837251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3838251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3839251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3840251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3841251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3842251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3843251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3844251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3845251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3846251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3847251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3848251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3849251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3850251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3851251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3852251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3853251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3854251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3855251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3856251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3857251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3858251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3859251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3860251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3861251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3862251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3863251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3864251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3865251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3866251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3867251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3868251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3869251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3870251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3871251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3872251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3873251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3874251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3875a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3876a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3877a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3878359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3879756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtT2LdrdPre(MCInst &Inst,
3880a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3881a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3882a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3883a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3884a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3885a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3886a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3887a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3888a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3889a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3890a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3891a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3892a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3893a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3894a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3895359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3896756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtT2StrdPre(MCInst &Inst,
3897a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3898a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3899a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3900a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3901a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3902a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3903a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3904a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3905a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3906a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3907a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3908a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3909eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3910eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3911eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3912359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3913756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst,
3914eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3915eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3916eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3917eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3918eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3919eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3920eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3921eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3922eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3923eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3924ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3925ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3926ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3927359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3928756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStWriteBackRegT2AddrModeImm8(MCInst &Inst,
3929ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3930ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3931ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3932ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3933ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3934ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3935ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3936ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
39371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3938ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3939ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3940359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3941756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdWriteBackRegAddrMode2(MCInst &Inst,
3942ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3943ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3944ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3945ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3946ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3947ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
39487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3949ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3950ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3951ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
39529ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
39539ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39549ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
3955359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3956756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdWriteBackRegAddrModeImm12(MCInst &Inst,
39579ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39589ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39599ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
39609ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
39619ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
39629ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
39639ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
39649ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39659ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
39669ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
39679ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3968548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3969548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3970548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3971359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3972756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStWriteBackRegAddrModeImm12(MCInst &Inst,
3973548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3974548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3975548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3976548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3977548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3978548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3979548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3980548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
39811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3982ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3983ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3984359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3985756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStWriteBackRegAddrMode2(MCInst &Inst,
3986ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3987ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3988ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3989548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3990548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3991548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
39937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
39947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
39957b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39967b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
3997359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3998756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStWriteBackRegAddrMode3(MCInst &Inst,
39997b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40007b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
40017b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40027b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40037b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
40047b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40057b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
40067b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
40077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
40087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4010359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4011756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdExtTWriteBackImm(MCInst &Inst,
40127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
4014ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
40167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
40217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
4022ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4023ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
4024ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
40257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
4026ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
4027ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
4028359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4029756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdExtTWriteBackReg(MCInst &Inst,
40307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
4032aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
4033ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
4034ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
40357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
40397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
40407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
4042aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4046359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4047756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStExtTWriteBackImm(MCInst &Inst,
40487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
40507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
40527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
40577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
4058ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4059ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
4060ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
40617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
4062ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
4063ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
4064359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4065756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStExtTWriteBackReg(MCInst &Inst,
40667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4067ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
4068ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
40697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
4070ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
40757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
4076ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4077ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
4078ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
40792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
40802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4082359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4083756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdrdPre(MCInst &Inst,
40842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
40862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
40882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
40892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
40912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
40922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
40932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
40952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
409614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
409714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
409814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4099359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4100756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtStrdPre(MCInst &Inst,
410114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
410214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
410314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
410414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
410514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
410614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
410714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
410814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
410914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
411014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
411114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
411214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
4113623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
4114623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
4115623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4116359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4117756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtLdWriteBackRegAddrMode3(MCInst &Inst,
4118623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4119623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
4120623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
4121623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
4122623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
4123623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4124623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
4125623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
41261122fc40c16785d510025daeb6c72a075f7e2e5bChad Rosier/// cvtThumbMultiply - Convert parsed operands to MCInst.
412788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
412888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
4129359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4130756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtThumbMultiply(MCInst &Inst,
413188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
413288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
413388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
41341b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
41351b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
41361b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
41371b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
41381b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
41391b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
41401b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
41411b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
41421b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
414388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
414488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
4145623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
4146359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4147756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtVLDwbFixed(MCInst &Inst,
414812431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
414912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
41506029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
415112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
415212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
415312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
415412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
415512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
415612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
415712431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
415812431329d617064d6e72dd040a58c1635cc261abJim Grosbach
4159359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4160756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtVLDwbRegister(MCInst &Inst,
416112431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
416212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
41636029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
416412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
416512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
416612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
416712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
416812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
416912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
417012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
417112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
417212431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
417312431329d617064d6e72dd040a58c1635cc261abJim Grosbach
4174359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4175756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtVSTwbFixed(MCInst &Inst,
41764334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
41774334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
41784334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
41794334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
41804334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
41814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
41826029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
41834334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
41844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
41854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
41864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4187359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4188756d2cc2f7f6745603fdc0ec1ed4476d06385845Chad RosiercvtVSTwbRegister(MCInst &Inst,
41894334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
41904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
41914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
41924334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
41934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
41944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
41954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
41964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
41976029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
41984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
41994334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
42004334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
42014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4202e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
42039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
420450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
42057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4206762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
420718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4208a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
4209762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
4210b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
4211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
421218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
42131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
42147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
42157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
4216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42170571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
42180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
42190571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
42207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
42210571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
42227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
4223762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
4224b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
4225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
422757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
422803f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
4229fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
4230fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
4231fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
4232fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4233fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
4234fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
4235fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
42367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
42377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
423850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
42397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
42407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
424150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
424257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
424357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
424457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
424557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
424657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
424757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
424857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
424957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
425057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
425157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
425257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
425357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
425457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
425557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
425657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
425757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
425857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
425957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
426057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
4261eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
4262eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4263eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
4264eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
426557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
426657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
426757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
426857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
426957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
427057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
427157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
427257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
427357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
427457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
427557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
427657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
427757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
427857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
427957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
428057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
428157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
428257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
428357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
428457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
428557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
428657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
428757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
428857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
428957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
429057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
429157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
429257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
42936cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
42946cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
42956cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
42968a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
42976cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
42988a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
42996cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
43007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
430150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
43020da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
43037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
43047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
43057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
430605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
43077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
43087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
43097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
43107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
43117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
43127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
43137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43140da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
43150da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
43160da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
43170da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
43180da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
43197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
43207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
43217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
43227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
43237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
432405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
43257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
43267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
43277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
432857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
432957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
43327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
43337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
43347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
43357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4336762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
43377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
43399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4340d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
43417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
43427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
43437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
43447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
43457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
43467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
43477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
43487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
43497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
43509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
43527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
43537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
43547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
43557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
43577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
43580d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
43597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
43607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
43610d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
43627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
43639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
436416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
43657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
43667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
43677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
43687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
43697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
43707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
437257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
43737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
43747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4375f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4376f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4377f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4378f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4379f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4380f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
43819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
43839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
43849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4387a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
43887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
43897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
43907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
43917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
439218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4393a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4394a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
439538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4396af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4397af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
43980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
44000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4401a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
44020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4403a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
44040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4405a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
44060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4407a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
44087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4409b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4410a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
44117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
44127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
44137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
44147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
44157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
44167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
44178a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
44188a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
44197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
44207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
44219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
44227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
44237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
44247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
44257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
44267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
44277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
44287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
44297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
44307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
44317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
44327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
44337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
44347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
44357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
44367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
44377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4438a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4440a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4441a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
44429d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
44439d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
44449d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
444551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Anything that can accept a floating point constant as an operand
444651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // needs to go through here, as the regular ParseExpression is
444751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // integer only.
444851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  //
444951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // This routine still creates a generic Immediate operand, containing
445051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // a bitcast of the 64-bit floating point value. The various operands
445151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // that accept floats can check whether the value is valid for them
445251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // via the standard is*() predicates.
445351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
44549d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
44559d39036f62674606565217a10db28171b9594bc7Jim Grosbach
44568a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
44578a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
44589d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
44590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
44600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
44610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
44620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
44630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
44640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
44650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
44660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
44670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
44680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
44690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
44700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
44710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
44720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
44730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
44740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
44759d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
44769d39036f62674606565217a10db28171b9594bc7Jim Grosbach
44779d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
44789d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
44799d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
44809d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
44819d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
44829d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
44839d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
4484ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  SMLoc Loc = Tok.getLoc();
44859d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
448651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
44879d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
44889d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
448951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    IntVal ^= (uint64_t)isNegative << 31;
44909d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
449151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
449251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          MCConstantExpr::Create(IntVal, getContext()),
449351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          S, Parser.getTok().getLoc()));
44949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
44959d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
449651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Also handle plain integers. Instructions which allow floating point
449751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // immediates also allow a raw encoded 8-bit value.
44989d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
44999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
45009d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
45019d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
4502ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach      Error(Loc, "encoded floating point value out of range");
45039d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
45049d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
450551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    double RealVal = ARM_AM::getFPImmFloat(Val);
450651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
450751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
450851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        MCConstantExpr::Create(Val, getContext()), S,
450951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        Parser.getTok().getLoc()));
45109d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
45119d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
45129d39036f62674606565217a10db28171b9594bc7Jim Grosbach
4513ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  Error(Loc, "invalid floating point immediate");
45149d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
45159d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
451651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
45179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
45189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
45191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4520fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4521762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4522fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4523fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4525f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4526f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4527fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4528f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4529f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4530f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4531f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4532f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4533fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4534a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4535146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4536146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
453750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
453819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
45391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
454050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
45410d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
454219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
45430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
454419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
454519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
45463cbe43fe69680df772d83947ced97ca445861213Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
4547b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    if (Mnemonic == "vmrs" &&
4548b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach        Parser.getTok().getString().equals_lower("apsr_nzcv")) {
45495cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
45505cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
4551b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach      Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S));
45525cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
45535cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4554e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4555e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4556e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
455719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4558758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
455967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
45606284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
456167b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4562515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4563515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4564515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4565762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4566515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
456750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4568762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
456950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
457050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
457150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4572a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
45731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4574d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
45751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
45768a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
457763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4578079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4579762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4580b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4581b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach
4582b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Colon)) {
4583b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      bool isNegative = Parser.getTok().is(AsmToken::Minus);
4584b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      const MCExpr *ImmVal;
4585b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      if (getParser().ParseExpression(ImmVal))
4586b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach        return true;
4587b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4588b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      if (CE) {
4589b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach        int32_t Val = CE->getValue();
4590b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach        if (isNegative && Val == 0)
4591b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach          ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
4592b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      }
4593b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4594b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
4595b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      return false;
459663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4597b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach    // w/ a ':' after the '#', it's just like a plain ':'.
4598b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach    // FALLTHROUGH
459963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
46009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
46019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
46027597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
46037597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
46047597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
46051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
46069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
46079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46087597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
46097597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
46109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
46119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46127597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
46137597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
46149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
46157597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
46169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
46179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4620a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
46211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
46227597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
46231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
46247597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
46259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
46278a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
46289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
46299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
46319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
46329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
46339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
46349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
46369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
46377597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
46389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
46397597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
46409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
46419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
46429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
46439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
46449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
46459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
46479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
46489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
46499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
46509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
46519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
46529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
46539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4654352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4655352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4656352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4657badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
465889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
46591355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
46605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
46615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
466289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
466389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4664352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4665352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4666a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4667352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4668badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4669352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4670352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
46715f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
46725f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
46735f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
46745f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
46755f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
46765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
46775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
46786849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
46796849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "fmuls")
4680352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4681badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
46823f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
46833f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4684ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
468571725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
468604d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
46872f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
46883f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
46893f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
46903f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
46913f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
46923f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
46933f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
46943f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
46953f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
46963f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
46973f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
46983f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
46993f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
47003f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
47013f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
47023f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
47033f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
47043f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
47053f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
47063f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
47073f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
47083f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
47093f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
47103f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
471152925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4712345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4713352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4714352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4715352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
471600f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
47175f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
47185f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
47195f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
472067ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
472148171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
47229c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach        Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
47236357caec785268d1e39059d03eb2034dee65467fJim Grosbach        Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" ||
472482509e5c62a99912c636b22e227b810eaf6eda78Evan Cheng        Mnemonic == "vfms" || Mnemonic == "vfnms" ||
4725e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4726352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4727352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4728352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4729352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4730a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4731a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4732a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4733a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4734a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4735a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4736a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4737a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4738a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4740a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4741a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4742a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4743a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4744a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
474589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
474689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
474789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
474889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
474989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
475089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4751352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4752352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
47533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
47543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
47553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
47563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
47573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4758fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
47591355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4760fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4761eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4762eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
47633443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4764eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4765d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4766eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4767d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
476882509e5c62a99912c636b22e227b810eaf6eda78Evan Cheng      Mnemonic == "vfm" || Mnemonic == "vfnm" ||
47693443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4770d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4771d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4772eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4773fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4774eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
47753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4776eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4777eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4778eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4779eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4780ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4781ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
47820780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
47832bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
47842bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
47852bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
47864af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
47874af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
47881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
47893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4790fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
47913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4792fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4793fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4794fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
479563b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4796fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4797fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4798badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4799badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4800d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4801d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
480220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
480320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4804d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4805d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4806d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4807d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4808d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4809d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4810d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4811d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4812d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
48138adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4814d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4815d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4816d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4817d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
48183912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
48193912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
48203912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
48213912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
48223912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
48233912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
48243912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
48253912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
482672f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
482720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
482820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
482920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4830f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4831f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4832f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
483372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
483472f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
483572f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
483620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
4837a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach      ((Mnemonic == "add" &&static_cast<ARMOperand*>(Operands[5])->isReg()) ||
483820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
483972f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4840f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4841f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
484220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
484320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
484420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4845f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4846f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
484720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
484820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
484920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
485020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
485120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
485220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
485320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
485412a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // check against T3. If the second register is the PC, this is an
485512a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // alternate form of ADR, which uses encoding T4, so check for that too.
485620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
485720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
485812a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC &&
485920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
486020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
486120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
486220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
486320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
486464944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
486520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
486620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
486720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
486820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
486920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
487020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
487120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
487220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
487320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
487464944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
487564944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
487664944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
487764944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
487864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
487964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
488064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
488164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
488264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
488364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
488464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
488564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
488664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
488764944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
48881de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
488964944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
489064944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
489164944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
489264944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
489364944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
489464944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
489564944f48a1164c02c15ca423a53919682a89074cJim Grosbach
48967f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
48977f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
48987f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
48997f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
49007f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
49017f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
49027f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
49037f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
49047f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
49057f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
49067f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
49077f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
49087f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
49097f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
491064944f48a1164c02c15ca423a53919682a89074cJim Grosbach
491120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4912f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4913f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4914f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4915f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4916f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4917f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4918f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
491972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
492072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
4921a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
4922a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach      (static_cast<ARMOperand*>(Operands[4])->isImm() ||
4923a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach       (Operands.size() == 6 &&
4924a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm())))
492572f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
49263912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4927d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4928d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4929d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
49307aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
49317aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
49327aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
49337aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
49347aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
49357aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
49367aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
49377aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
49387aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
49397aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
49407aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
49417aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
49427aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
49437aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
49447aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
49457aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
494621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4947badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4948badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4949badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
495021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
495121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
495221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
495321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
495421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
495521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
495621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
495721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4958a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4959a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4960a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4961a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4962a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4963a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4964a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4965a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4966a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4967badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4968badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4969ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4970badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4971352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4972352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4973a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4974352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
497589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
49761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
497789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4978badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
49790c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
49800c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
49810c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
49820c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
49830c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
49840c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4985ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4986ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
498789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
498889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
498989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
499089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
499189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
499289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4993f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4994f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4995f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4996f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4997f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
499889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
499989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
500089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
500189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
500289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
5003f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
500489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
500589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
500689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
500789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
500889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
5009f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
501089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
501189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
5012ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
5013ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
50149717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
50153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
50163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
50173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
50183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
50193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
50203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
50213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
50223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
50231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
50243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
502533c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
502633c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
502733c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
502833c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
5029ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
503033c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
503133c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
5032c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
5033c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
5034c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
5035c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
5036c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
5037c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
5038c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
503933c16a27370939de39679245c3dff72383c210bdJim Grosbach
50403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
5041f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
5042f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
50433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
5044f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
5045f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
50463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
50473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
50483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
5049f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
5050f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
50513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
5052f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
5053badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
5054345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
5055a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
5056a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
5057a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
5058a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
5059a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
5060a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
5061a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
5062345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
50635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
50645747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
50655747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
5066a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
5067a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
50687aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
50697aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
50707aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
50717aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
50727aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
50737aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
507481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
507581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
507681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
507781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
50785747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
50795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
50805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
50815747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5082a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
50831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
5084cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
5085cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
5086cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
5087a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5088a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
5089b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
5090a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5091a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
50921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
5093cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
5094cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
5095cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
5096a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
5097a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
509816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
5099cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5100186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
5101cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
5102186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
5103cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
5104146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
510534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
5106ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
5107d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
5108d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
5109d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
511020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
511120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
511220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
511320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
511420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
5115ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5116ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
5117ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
5118ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
5119ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
5120cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
5121cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
5122cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
512321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
512421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
5125cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
5126cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
5127cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5128cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
5129cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
5130cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
5131857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
5132857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
5133857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
5134857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
5135857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
5136857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
5137857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5138857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5139857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
5140857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
5141857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
5142857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
514368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
514468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
514568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
514668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
514768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
514868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
514968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
515068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
515168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
515268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
515368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5154857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
5155857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
5156857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
5157934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
515855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
515955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
5160934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
516155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
516255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
5163934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5164934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5165934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
516655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
516755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
5168d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
5169d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
5170d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
517155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
5172d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
5173934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
5174934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5175934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
5176934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
5177934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
5178934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
51799898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
5180ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5181ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5182189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
5183aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
5184aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
5185aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
5186aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
5187aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
5188aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
5189aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
5190aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
5191aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
5192aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
5193aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
5194aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
5195aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
5196aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
5197aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
5198aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
5199aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
5200aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
520176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
520276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
520376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
520476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
520576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
520676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
520776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
520876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
520976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
521076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
521176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
5212f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
5213f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
5214f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
5215f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
52161a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5217f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
52181a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
5219f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
5220f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
5221f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5222189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
5223189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
5224189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
5225189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
52261a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
5227f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
5228f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
522974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // NOTE: BKPT instruction has the interesting property of being
523074423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // allowed in IT blocks, but not being predicable.  It just always
5231b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
523274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT &&
523374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      Inst.getOpcode() != ARM::BKPT) {
5234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
5235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
5236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
5237f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
5238a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
5239f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
5240f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
5241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
5242f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
5243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
5244f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
5245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
5246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
5247f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
5248f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
5249f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
5250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
5251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
5252f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
5253f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
5254f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
5255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
5256c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
5257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
5258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
525951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
526051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
5261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
5262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5263189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
52642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
52652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
52662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
5267189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
5268189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5269df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
5270df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
5271189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
5272189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5273189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
5274189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5275189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
527614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
527714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
5278df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
5279df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
528014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
528114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
528214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
528314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
528414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
528553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
528653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
5287189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
5288189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5289df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
5290df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(2).getReg());
5291189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
529214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5293189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
5294189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5295189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5296fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
5297fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
5298fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
5299fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
5300fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
5301fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
5302fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
5303fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
530400c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
5305fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
530693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
530776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
530876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
530976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
531076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
531176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
531293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
531393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
531493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
53157260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
53167260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
53177260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
5318aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
531976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
5320aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
5321aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
532293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
532376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
532493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
532593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
532676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
532776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
5328aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
53297260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
53307260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
53317260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
533293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
533393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
533493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
533576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
533676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
533776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
533876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
533976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
534076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
534176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
534264b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier  case ARM::tMUL: {
534364b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    // The second source operand must be the same register as the destination
534464b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    // operand.
5345429af6fa4124d8b6dd310069e0a44dcacb35fc8aChad Rosier    //
5346429af6fa4124d8b6dd310069e0a44dcacb35fc8aChad Rosier    // In this case, we must directly check the parsed operands because the
5347429af6fa4124d8b6dd310069e0a44dcacb35fc8aChad Rosier    // cvtThumbMultiply() function is written in such a way that it guarantees
5348429af6fa4124d8b6dd310069e0a44dcacb35fc8aChad Rosier    // this first statement is always true for the new Inst.  Essentially, the
5349429af6fa4124d8b6dd310069e0a44dcacb35fc8aChad Rosier    // destination is unconditionally copied into the second source operand
5350429af6fa4124d8b6dd310069e0a44dcacb35fc8aChad Rosier    // without checking to see if it matches what we actually parsed.
535164b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    if (Operands.size() == 6 &&
535264b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier        (((ARMOperand*)Operands[3])->getReg() !=
535364b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier         ((ARMOperand*)Operands[5])->getReg()) &&
535464b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier        (((ARMOperand*)Operands[3])->getReg() !=
535564b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier         ((ARMOperand*)Operands[4])->getReg())) {
5356fafa283e65bca1473eace94057077129a76dbdccChad Rosier      return Error(Operands[3]->getStartLoc(),
5357fafa283e65bca1473eace94057077129a76dbdccChad Rosier                   "destination register must match source register");
535864b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    }
535964b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    break;
536064b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier  }
53615402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
53625402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
53635402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
53646dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5365aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
53665402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
53675402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5368aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5369aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
53706dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
53716dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
53726dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5373aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
53745402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
53755402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5376aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5377aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
53786dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
53796dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
53801e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
53811e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
53828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
53831e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
53841e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
53851e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
53861e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5387a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  case ARM::tADDrSP: {
5388a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // If the non-SP source operand and the destination operand are not the
5389a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // same, we need thumb2 (for the wide encoding), or we have an error.
5390a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    if (!isThumbTwo() &&
5391a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach        Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
5392a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      return Error(Operands[4]->getStartLoc(),
5393a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach                   "source register must be the same as destination");
5394a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    }
5395a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    break;
5396a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  }
5397189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5398189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5399189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5400189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5401189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5402d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
540384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
5404bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
54059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
54067945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
54077945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
54087945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
54097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
54107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
54117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
54127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_8:  Spacing = 1; return ARM::VST1LNd8;
54137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
54147945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
54159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
54177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
54187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
54197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
54207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
54217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
54227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
54237945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
54247945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
54257945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
54267945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
54277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
54287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
54297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_8:  Spacing = 1; return ARM::VST2LNd8;
54307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
54317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
54327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
54337945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
5434d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
54354adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  // VST3LN
54367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
54377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
54387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
54397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
54407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
54417945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
54427945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
54437945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
54447945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
54457945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
54467945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_8:  Spacing = 1; return ARM::VST3LNd8;
54477945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
54487945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
54497945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
54507945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
54514adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
5452d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3
54537945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
54547945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
54557945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
54567945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
54577945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
54587945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
54597945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
54607945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
54617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
54627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
54637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
54647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
54657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_8:  Spacing = 1; return ARM::VST3d8;
54667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
54677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
54687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_8:  Spacing = 2; return ARM::VST3q8;
54697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
54707945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
5471539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
547288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  // VST4LN
547388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
547488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
547588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
547688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
547788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
547888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
547988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
548088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
548188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
548288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
548388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:  Spacing = 1; return ARM::VST4LNd8;
548488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
548588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
548688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
548788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
548888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
5489539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4
5490539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5491539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5492539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5493539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5494539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5495539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5496539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5497539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5498539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5499539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5500539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5501539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5502539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:  Spacing = 1; return ARM::VST4d8;
5503539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
5504539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
5505539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:  Spacing = 2; return ARM::VST4q8;
5506539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
5507539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
550884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
550984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
551084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
5511d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
55127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
5513bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
55149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
55157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
55167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
55177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
55187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
55197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
55207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
55217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_8:  Spacing = 1; return ARM::VLD1LNd8;
55227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
55237945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
55249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
55267945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
55277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
55287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
55297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
55307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
55317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
55327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
55337945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
55347945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
55357945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
55367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_8:  Spacing = 1; return ARM::VLD2LNd8;
55377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
55387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
55397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
55407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
55413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
55425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP
55435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
55445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
55455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
55465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
55475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPq16_UPD;
55485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
55495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
55505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
55515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
55525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
55535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
55545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
55555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:  Spacing = 1; return ARM::VLD3DUPd8;
55565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
55575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
55585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
55595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
55605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
55615e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
55623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  // VLD3LN
55637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
55647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
55657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
55667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
55677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
55687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
55697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
55707945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
55717945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
55727945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
55737945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_8:  Spacing = 1; return ARM::VLD3LNd8;
55747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
55757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
55767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
55777945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
5578c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
5579c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3
55807945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
55817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
55827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
55837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
55847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
55857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
55867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
55877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
55887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
55897945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
55907945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
55917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
55927945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_8:  Spacing = 1; return ARM::VLD3d8;
55937945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
55947945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
55957945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;
55967945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
55977945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
55988abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
5599e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  // VLD4LN
5600e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5601e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5602e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5603e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNq16_UPD;
5604e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5605e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5606e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5607e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5608e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
5609e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5610e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:  Spacing = 1; return ARM::VLD4LNd8;
5611e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
5612e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
5613e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
5614e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
5615e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
5616a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP
5617a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5618a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5619a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5620a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
5621a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
5622a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5623a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5624a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5625a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5626a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
5627a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
5628a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5629a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:  Spacing = 1; return ARM::VLD4DUPd8;
5630a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
5631a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
5632a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
5633a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
5634a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
5635a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
56368abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  // VLD4
56378abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
56388abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
56398abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
56408abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
56418abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
56428abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
56438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
56448abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
56458abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
56468abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
56478abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
56488abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
56498abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8;
56508abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
56518abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
56528abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8;
56538abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
56548abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
56557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
56567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
56577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
565883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5659f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5660f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5661f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
56620b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  // Aliases for alternate PC+imm syntax of LDR instructions.
56630b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRpcrel:
56640b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRpci);
56650b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56660b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRBpcrel:
56670b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRBpci);
56680b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56690b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRHpcrel:
56700b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRHpci);
56710b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56720b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSBpcrel:
56730b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSBpci);
56740b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56750b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSHpcrel:
56760b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSHpci);
56770b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
56798b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
56808b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
56818b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32: {
568284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
568384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
568484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
56855b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5686d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
568784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
568884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
568984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
569084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
569184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
569284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
569384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
569484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
569584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
569684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
569784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
56989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
57008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
57018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
57028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
57038b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32: {
57049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
57059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
57075b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5708d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
57109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
57139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57145b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57155b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
57169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
57189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
57199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
57209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
57219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
57224adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
57234adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:
57244adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16:
57254adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32:
57264adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16:
57274adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: {
57284adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
57294adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57304adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
57314adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
57324adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57334adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
57344adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57354adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57364adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
57374adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57384adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57394adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
57404adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57414adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
57424adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
57444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
57454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
57464adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
57474adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
57484adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
574988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:
575088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16:
575188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32:
575288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16:
575388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: {
575488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
575588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
575688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
575788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
575888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
575988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
576088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
576188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
576288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
576388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
576488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
576588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
576688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
576788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
576888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
576988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
577088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
577188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
577288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
577388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
577488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
577588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
577688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
57778b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
57788b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
57798b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: {
578084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
578184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
578284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
57835b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5784d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
578584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
578684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
578784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
578884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
578984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
579084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
579184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
579284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
579384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
579484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
579584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
57969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
57978b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
57988b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
57998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
58008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
58018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: {
58029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
58055b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5806d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
58079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
58119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58125b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58135b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
58149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
58169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
58179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
58189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
58199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
58204adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
58214adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:
58224adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16:
58234adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32:
58244adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16:
58254adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: {
58264adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
58274adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58284adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
58294adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
58304adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
58314adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58324adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58334adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58344adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
58354adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58364adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58374adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
58384adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58394adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
58404adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58414adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
58424adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
58434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
58444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
58454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
58464adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
584788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:
584888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16:
584988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32:
585088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16:
585188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: {
585288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
585388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
585488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
585588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
585688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
585788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
585888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
585988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
586088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
586188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
586288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
586488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
586688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
586888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
586988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
587088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
587188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
587288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
587388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
587488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
58758b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
58768b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
58778b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32: {
587884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
587984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
588084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
58815b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5882d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
588384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
588484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
588584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
588684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
588784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
588884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
588984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
589084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
589184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
58929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58938b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
58948b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
58958b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
58968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
58978b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32: {
58989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
59015b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5902d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
59039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59065b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59075b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
59089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
59129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
59139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
59144adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
59154adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_8:
59164adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_16:
59174adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_32:
59184adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_16:
59194adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_32: {
59204adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
59214adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59224adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
59234adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
59244adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
59254adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59264adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59274adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59284adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59294adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
59304adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59314adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
59324adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59334adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59344adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
593588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
593688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
593788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
593888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
593988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:
594088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16:
594188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32:
594288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16:
594388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: {
594488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
594588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
594688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
594788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
594888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
594988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
595088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
595188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
595288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
595488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
595688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
595888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
595988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
596088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59614adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
59624adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
59634adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
59644adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
59659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
59668b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
59678b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
59688b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: {
5969872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5970872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5971872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
597295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5973d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5974872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5975872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5976872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5977872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5978872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5979872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5980872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5981872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5982872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5983872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5984872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5985872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
59869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59878b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
59888b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
59898b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
59908b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
59918b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: {
59929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
59939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
599595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5996d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
599895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
599995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
60019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
60049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
600595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
600695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
60099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
60109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
60119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
60129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
60139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
60143a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
60153a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
60163a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
60173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
60183a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: {
60193a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
60203a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
60213a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
60223a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6023d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60243a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60253a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60263a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60273a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6028c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60293a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
60303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
60333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60363a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6037c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
60403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
60413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
60423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
60433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
60443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6045e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:
6046e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16:
6047e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32:
6048e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16:
6049e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: {
6050e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6051e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6052e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6053e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6054e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6055e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6056e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6057e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6058e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6059e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6060e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6061e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6062e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6063e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6064e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6065e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
6066e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6067e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6068e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6069e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6070e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6071e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6072e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6073e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6074e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
6075e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
6076e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6077e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6078e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6079e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
60808b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
60818b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
60828b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: {
6083872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
6084872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
6085872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
608695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6087d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6088872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6089872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6090872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6091872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6092872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6093872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6094872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6095872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6096872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6097872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
6098872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
6099872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
61009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
61018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
61028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
61038b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
61048b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
61058b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: {
61069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
61079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
61089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
610995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6110d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
611295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
611395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
61149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
61159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
61169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
61179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
611995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
612095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
61219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
61229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
61259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
61269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
61279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
61283a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
61293a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
61303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
61313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
61323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: {
61333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
61343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
61353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
61363a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6137d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6142c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
61443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
61453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
61463a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61473a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
61483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6151c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
61533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
61563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
61573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
61583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6159e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:
6160e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16:
6161e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32:
6162e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16:
6163e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: {
6164e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6165e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6166e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6167e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6168e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6169e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6170e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6171e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6172e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6173e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6174e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6175e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6176e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6177e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6178e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6179e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6180e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6181e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6182e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6183e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6184e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6185e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6186e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6187e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6188e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6189e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6190e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6191e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6192e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6193e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
61948b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
61958b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
61968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32: {
61977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
61987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
61997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
620095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6201d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
62037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
62047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
62057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
62067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
62077636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62087636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
62107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
62117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
62129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
62138b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
62148b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
62158b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
62168b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
62178b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32: {
62189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
62199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
62209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
622195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6222d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
622495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
622595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
62269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
62279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
62289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
622995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
623095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
62319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
62329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
62359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
62369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
62373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
62383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
62393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
62403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
62413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
62423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32: {
62433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
62443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
62453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
62463a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6247d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
62493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
62513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6252c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
62533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
62543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
62553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
62563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
62583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6259c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
62603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
62613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
62643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
62653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
62663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6267e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:
6268e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16:
6269e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32:
6270e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16:
6271e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: {
6272e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6273e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6274e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6275e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6276e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6277e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6278e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6279e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6280e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6281e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6282e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6283e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6284e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6285e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6286e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6287e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6288e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6289e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6290e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6291e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6292e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6293e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6294e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6295e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6296e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6297e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6298e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6299e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
63005e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP single 3-element structure to all lanes instructions.
63015e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:
63025e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16:
63035e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32:
63045e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8:
63055e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16:
63065e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: {
63075e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
63085e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
63095e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63105e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63115e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63125e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
63135e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63145e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
63155e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63165e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63175e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63185e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63195e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
63205e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
63215e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
63225e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
63235e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:
63245e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16:
63255e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32:
63265e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8:
63275e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16:
63285e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: {
63295e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
63305e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
63315e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63325e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63335e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63345e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
63355e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63365e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
63375e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63385e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
63395e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63405e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
63415e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
63445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
63455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
63465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
63475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:
63485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16:
63495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32:
63505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8:
63515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16:
63525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: {
63535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
63545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
63555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
63595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
63615e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63625e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
63635e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63645e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
63655e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
63665e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
63675e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
63685e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
63695e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
63705e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
6371c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3 multiple 3-element structure instructions.
6372c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_8:
6373c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_16:
6374c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_32:
6375c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_8:
6376c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_16:
6377c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_32: {
6378c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6379c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6380d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6381c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6382c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6383c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6384c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6385c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6386c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6387c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6388c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6389c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6390c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6391c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6392c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6393c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6394c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:
6395c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16:
6396c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32:
6397c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:
6398c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16:
6399c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: {
6400c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6401c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6402d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6403c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6404c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6405c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6406c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6407c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6408c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6409c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6410c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6411c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6412c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6413c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6414c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6415c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6416c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6417c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6418c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:
6419c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_16:
6420c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_32:
6421c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:
6422c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_16:
6423c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: {
6424c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6425c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6426d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6427d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6428d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6429d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6430d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6431d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6432d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6433d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6434d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6435d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6436d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6437d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6438d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6439d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6440d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6441d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6442a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP single 3-element structure to all lanes instructions.
6443a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:
6444a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16:
6445a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32:
6446a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8:
6447a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16:
6448a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: {
6449a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6450a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6451a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6452a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6453a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6454a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6455a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6456a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6457a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6458a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6459a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6460a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6461a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6462a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6463a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6464a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6465a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6466a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6467a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:
6468a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16:
6469a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32:
6470a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8:
6471a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16:
6472a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: {
6473a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6474a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6475a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6476a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6477a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6478a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6479a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6480a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6481a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6482a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6483a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6484a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6485a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6486a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6487a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6488a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6489a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6490a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6491a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6492a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6493a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:
6494a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16:
6495a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32:
6496a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8:
6497a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16:
6498a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: {
6499a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6500a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6501a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6502a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6503a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6504a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6505a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6506a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6507a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6508a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6509a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6510a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6511a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6512a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6513a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6514a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6515a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6516a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6517a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6518a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6519a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4 multiple 4-element structure instructions.
65208abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:
65218abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16:
65228abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32:
65238abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:
65248abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16:
65258abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: {
65268abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
65278abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
65288abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
65298abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
65308abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65318abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
65328abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65338abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
65348abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65358abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
65368abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65378abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
65388abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
65398abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
65408abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
65418abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
65428abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
65438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
65448abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:
65458abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16:
65468abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32:
65478abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:
65488abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16:
65498abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: {
65508abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
65518abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
65528abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
65538abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
65548abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65558abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
65568abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65578abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
65588abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65598abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
65608abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65618abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
65628abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
65638abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
65648abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
65658abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
65668abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
65678abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
65688abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
65698abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
65708abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:
65718abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16:
65728abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32:
65738abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:
65748abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16:
65758abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: {
65768abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
65778abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
65788abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
65798abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
65808abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65818abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
65828abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65838abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
65848abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65858abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
65868abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65878abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
65888abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
65898abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
65908abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
65918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
65928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
65938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
65948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
65958abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
6596d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3 multiple 3-element structure instructions.
6597d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_8:
6598d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_16:
6599d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_32:
6600d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_8:
6601d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_16:
6602d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_32: {
6603d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6604d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6605d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6606d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6607d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6608d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6609d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6610d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6611d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6612d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6613d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6614d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6615d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6616d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6617d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6618d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6619d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:
6620d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16:
6621d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32:
6622d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:
6623d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16:
6624d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: {
6625d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6626d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6627d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6628d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6629d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6630d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6631d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6632c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6633c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6634c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6635c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6636c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6637d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6638d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6639d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6640d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6641d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6642d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6643d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_8:
6644d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_16:
6645d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_32:
6646d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_8:
6647d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_16:
6648d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_32: {
6649d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6650d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6651d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6652c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6653c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6654c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6655c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6656d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6657d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6658d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6659d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6660d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6661c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6662c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6663c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6664c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6665c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6666c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6667539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4 multiple 3-element structure instructions.
6668539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:
6669539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16:
6670539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32:
6671539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:
6672539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16:
6673539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: {
6674539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6675539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6676539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6677539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6678539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6679539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6680539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6681539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6682539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6683539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6684539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6685539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6686539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6687539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6688539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6689539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6690539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6691539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6692539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:
6693539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16:
6694539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32:
6695539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:
6696539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16:
6697539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: {
6698539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6699539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6700539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6701539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6702539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6703539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6704539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6705539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6706539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6707539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6708539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6709539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6710539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6711539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6712539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6713539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6714539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6715539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6716539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6717539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6718539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:
6719539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16:
6720539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32:
6721539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:
6722539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16:
6723539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: {
6724539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6725539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6726539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6727539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6728539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6729539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6730539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6731539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6732539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6733539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6734539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6735539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6736539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6737539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6738539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6739539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6740539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6741539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6742539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6743539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6744a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  // Handle encoding choice for the shift-immediate instructions.
6745a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  case ARM::t2LSLri:
6746a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  case ARM::t2LSRri:
6747a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  case ARM::t2ASRri: {
6748a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6749a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
6750a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach        Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) &&
6751a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach        !(static_cast<ARMOperand*>(Operands[3])->isToken() &&
6752a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) {
6753a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      unsigned NewOpc;
6754a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      switch (Inst.getOpcode()) {
6755a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      default: llvm_unreachable("unexpected opcode");
6756a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
6757a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
6758a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
6759a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      }
6760a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      // The Thumb1 operands aren't in the same order. Awesome, eh?
6761a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      MCInst TmpInst;
6762a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.setOpcode(NewOpc);
6763a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
6764a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
6765a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
6766a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
6767a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6768a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
6769a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      Inst = TmpInst;
6770a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      return true;
6771a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach    }
6772a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach    return false;
6773a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  }
6774a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach
6775863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
67762cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVsr:
67772cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVSsr: {
67782cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
67792cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // whether we're in an IT block if the register operands are low
67802cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // registers.
67812cc5cda464e7c936215281934193658cb799c603Jim Grosbach    bool isNarrow = false;
67822cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
67832cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
67842cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(2).getReg()) &&
67852cc5cda464e7c936215281934193658cb799c603Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
67862cc5cda464e7c936215281934193658cb799c603Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
67872cc5cda464e7c936215281934193658cb799c603Jim Grosbach      isNarrow = true;
67882cc5cda464e7c936215281934193658cb799c603Jim Grosbach    MCInst TmpInst;
67892cc5cda464e7c936215281934193658cb799c603Jim Grosbach    unsigned newOpc;
67902cc5cda464e7c936215281934193658cb799c603Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
67912cc5cda464e7c936215281934193658cb799c603Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
67922cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
67932cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
67942cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
67952cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
67962cc5cda464e7c936215281934193658cb799c603Jim Grosbach    }
67972cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.setOpcode(newOpc);
67982cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
67992cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isNarrow)
68002cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
68012cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
68022cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
68032cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
68042cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
68052cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
68062cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (!isNarrow)
68072cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
68082cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
68092cc5cda464e7c936215281934193658cb799c603Jim Grosbach    Inst = TmpInst;
68102cc5cda464e7c936215281934193658cb799c603Jim Grosbach    return true;
68112cc5cda464e7c936215281934193658cb799c603Jim Grosbach  }
6812863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
6813863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
6814863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
6815863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
6816863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
6817863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
6818863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6819863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6820863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
6821863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
6822863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
6823863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
6824863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
6825863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6826863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
6827863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
6828863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
6829863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
6830520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
6831863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
6832d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
6833d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    if (Amount == 32) Amount = 0;
6834863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
6835863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
6836863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
6837863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6838863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6839863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6840520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    if (newOpc != ARM::t2RRX)
6841d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer      TmpInst.addOperand(MCOperand::CreateImm(Amount));
6842863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6843863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6844863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
6845863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6846863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6847863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
6848863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
6849863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
6850863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
685123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
685223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
685323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
685423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
685523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
685623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
685723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
685823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
685923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
686023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
686123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
686223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
686323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
686423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
686523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
686623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
686723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
686823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
686923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
687023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
687123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
687223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
687323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
687423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
687523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
6876ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
6877ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
6878ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
6879ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
6880ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
6881ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
6882ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6883ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
6884ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
6885ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
6886ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
6887ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
6888ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
688948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
6890ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
6891b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    // A shift by 32 should be encoded as 0 when permitted
6892b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
6893b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton      Amt = 0;
6894ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
689571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
6896ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
689771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
689871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6899ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
6900ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
690171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
690271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
690371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
690471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
690583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
690671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
690748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
690848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
690948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
691048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
691148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
691248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
691348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
691448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
691548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
691648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
691748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
691848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
691948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
69200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
69210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
69220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
69230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
69240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
69250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
69260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
69270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
69280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
69290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
69300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
69310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
69320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
69330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
69340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
69350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
69360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
69370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
69380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
69390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
69400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
69410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
69420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
69430352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
69440352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
69450352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
69460352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
69470352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
69480352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
69490352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
69500352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
69510352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
6952f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
6953f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
6954f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
6955f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
6956f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
6957f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
6958f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
6959f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6960f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6961f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
6962f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
6963f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
6964f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6965f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6966f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
696783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6968f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
6969f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
6970f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
6971f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
6972f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
6973f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
6974f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
6975f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
6976f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
6977f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6978f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6979f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
6980f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
6981f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6982f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6983f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
6984f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
6985f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
6986da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
6987da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
6988da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
6989da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
6990da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6991da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6992da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
6993da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6994da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
6995da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
6996da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
6997da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
6998da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
6999da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
7000da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
7001da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
7002da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
7003da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
700489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
70050f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
70060f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
70070f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
70080f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
7009c0164f86080bc9d7a41fd5eabd0d6556396f5b38Jim Grosbach    if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
701089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
701183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
701283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
701389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
7014f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
7015f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
7016f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
7017f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
7018f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
7019c0164f86080bc9d7a41fd5eabd0d6556396f5b38Jim Grosbach    if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
7020f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
702183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
702283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
7023f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
70242d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach  case ARM::t2ADDri:
70252d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach  case ARM::t2SUBri: {
70262d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // If the destination and first source operand are the same, and
70272d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // the flags are compatible with the current IT status, use encoding T2
70282d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // instead of T3. For compatibility with the system 'as'. Make sure the
70292d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // wide encoding wasn't explicit.
70302d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
70318f1148bd07d57a1324ed39250642119baa540b7cJim Grosbach        !isARMLowRegister(Inst.getOperand(0).getReg()) ||
70322d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        (unsigned)Inst.getOperand(2).getImm() > 255 ||
70332d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        ((!inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) ||
70342d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        (inITBlock() && Inst.getOperand(5).getReg() != 0)) ||
70352d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
70362d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
70372d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach      break;
70382d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    MCInst TmpInst;
70392d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
70402d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach                      ARM::tADDi8 : ARM::tSUBi8);
70412d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
70422d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
70432d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
70442d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
70452d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
70462d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
70472d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    Inst = TmpInst;
70482d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    return true;
70492d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach  }
7050927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
7051927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
7052927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
7053927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
7054927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
7055927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
7056927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
7057713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
7058713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
7059927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
7060927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
7061927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
7062927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
7063927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
7064927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
7065927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
7066927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
7067927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
7068927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
7069927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
7070a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  case ARM::tADDrSP: {
7071a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // If the non-SP source operand and the destination operand are not the
7072a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // same, we need to use the 32-bit encoding if it's available.
7073a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
7074a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      Inst.setOpcode(ARM::t2ADDrr);
7075a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
7076a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      return true;
7077a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    }
7078a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    break;
7079a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  }
708051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
708151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
708283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
708351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
708483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
708583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
708651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
708751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
708851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
708983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
709051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
709183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
709283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
709351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
7094c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
7095a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
709683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
7097c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
709883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
709983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
7100c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
7101395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
7102395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
710383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
7104395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
710583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
710683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
71073ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
710876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
710976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
711076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
711176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
711276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
711376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
711476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
711576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
711676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
711776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
711876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
711976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
712076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
712176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
712276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
712376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
712476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
712576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
712676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
712776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
712876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
712983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
713076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
713176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
713276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
71338213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
71348213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
71358213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
71368213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
71378213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
71388213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
71398213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
71408213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
71418213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
71428213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
714383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
71448213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
71458213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
71468213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
71475402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
71485402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
71495402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
71505402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
71515402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
71525402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
715383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
71545402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
71555402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
71565402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
71575402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
71585402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
715983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
71605402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
71615402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
71625402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
71635402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
716483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
71655402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
71665402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
71675402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
71685402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
71695402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
717083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
71715402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
71721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
71731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
71741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
71751ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
7176c0164f86080bc9d7a41fd5eabd0d6556396f5b38Jim Grosbach        (unsigned)Inst.getOperand(1).getImm() <= 255 &&
7177c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
7178c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
7179c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
71801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
71811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
71821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
71831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
71841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
71851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
71861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
71871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
71881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
71891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
71901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
719183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
71921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
71931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
71941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
71951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
71961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
71971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
71981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
71991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
72001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
72011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
72021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
72031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
72041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
72051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
72061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
72071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
72081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
72091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
72101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
72111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
721283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
72131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
72141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
72151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
7216326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
721750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
721850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
721950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
7220326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
7221326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
7222326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
7223326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
7224326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
7225326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
7226326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
722750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
722850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
722950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
723050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
723150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
723250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
723350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
723450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
7235326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
7236326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
7237326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
7238326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
7239326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
7240326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
7241326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
7242326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
724383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
7244326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
7245326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
7246326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
724704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  case ARM::MOVsi: {
724804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
7249b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    // rrx shifts and asr/lsr of #32 is encoded as 0
7250b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
7251b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton      return false;
725204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
725304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      // Shifting by zero is accepted as a vanilla 'MOVr'
725404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      MCInst TmpInst;
725504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
725604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
725704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
725804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
725904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
726004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
726104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      Inst = TmpInst;
726204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      return true;
726304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    }
726404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    return false;
726504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  }
72668d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ANDrsi:
72678d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ORRrsi:
72688d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::EORrsi:
72698d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::BICrsi:
72708d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::SUBrsi:
72718d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ADDrsi: {
72728d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    unsigned newOpc;
72738d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
72748d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (SOpc == ARM_AM::rrx) return false;
72758d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    switch (Inst.getOpcode()) {
7276bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("unexpected opcode!");
72778d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
72788d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
72798d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::EORrsi: newOpc = ARM::EORrr; break;
72808d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::BICrsi: newOpc = ARM::BICrr; break;
72818d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
72828d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
72838d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
72848d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    // If the shift is by zero, use the non-shifted instruction definition.
72858ed97ef5f6980c689a5770ec30488601201e17c3Richard Barton    // The exception is for right shifts, where 0 == 32
72868ed97ef5f6980c689a5770ec30488601201e17c3Richard Barton    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
72878ed97ef5f6980c689a5770ec30488601201e17c3Richard Barton        !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
72888d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      MCInst TmpInst;
72898d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.setOpcode(newOpc);
72908d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
72918d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
72928d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
72938d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
72948d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
72958d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(6));
72968d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      Inst = TmpInst;
72978d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      return true;
72988d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
72998d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    return false;
73008d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  }
730174423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  case ARM::ITasm:
730289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
730389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
730489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
730589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
73064d2f077df1b46a126b5595d983f233ec896b757eRichard Barton    // of the condition code is zero.
730789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
730889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
7309f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
7310f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
731189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
731289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
731389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
731489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
73154d2f077df1b46a126b5595d983f233ec896b757eRichard Barton    }
731689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
7317f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
7318f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
7319f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
7320f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
7321f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
7322f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
7323f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
7324f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
732589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
732689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
73272b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2LSLrr:
73282b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2LSRrr:
73292b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ASRrr:
73302b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2SBCrr:
73312b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2RORrr:
73322b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2BICrr:
73332b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  {
7334c985e6ece66cf2046f0113da9eb2dec331a6b09fRichard Barton    // Assemblers should use the narrow encodings of these instructions when permissible.
73352b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
73362b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         isARMLowRegister(Inst.getOperand(2).getReg())) &&
73372b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
7338874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton        ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) ||
7339874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton         (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) &&
73402b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        (!static_cast<ARMOperand*>(Operands[3])->isToken() ||
73412b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         !static_cast<ARMOperand*>(Operands[3])->getToken().equals_lower(".w"))) {
73422b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      unsigned NewOpc;
73432b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      switch (Inst.getOpcode()) {
73442b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        default: llvm_unreachable("unexpected opcode");
73452b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
73462b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
73472b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
73482b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
73492b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2RORrr: NewOpc = ARM::tROR; break;
73502b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
73512b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      }
73522b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      MCInst TmpInst;
73532b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.setOpcode(NewOpc);
73542b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(0));
73552b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(5));
73562b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(1));
73572b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(2));
73582b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(3));
73592b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(4));
73602b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      Inst = TmpInst;
73612b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      return true;
73622b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    }
73632b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    return false;
73642b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  }
73652b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ANDrr:
73662b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2EORrr:
73672b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ADCrr:
73682b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ORRrr:
73692b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  {
7370c985e6ece66cf2046f0113da9eb2dec331a6b09fRichard Barton    // Assemblers should use the narrow encodings of these instructions when permissible.
73712b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    // These instructions are special in that they are commutable, so shorter encodings
73722b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    // are available more often.
73732b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
73742b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         isARMLowRegister(Inst.getOperand(2).getReg())) &&
73752b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
73762b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
7377874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton        ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) ||
7378874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton         (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) &&
73792b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        (!static_cast<ARMOperand*>(Operands[3])->isToken() ||
73802b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         !static_cast<ARMOperand*>(Operands[3])->getToken().equals_lower(".w"))) {
73812b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      unsigned NewOpc;
73822b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      switch (Inst.getOpcode()) {
73832b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        default: llvm_unreachable("unexpected opcode");
73842b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
73852b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
73862b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
73872b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
73882b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      }
73892b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      MCInst TmpInst;
73902b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.setOpcode(NewOpc);
73912b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(0));
73922b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(5));
73932b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
73942b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(1));
73952b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(2));
73962b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      } else {
73972b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(2));
73982b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(1));
73992b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      }
74002b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(3));
74012b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(4));
74022b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      Inst = TmpInst;
74032b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      return true;
74042b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    }
74052b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    return false;
74062b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  }
7407f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
740883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
7409f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
7410f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
741147a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
741247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
741347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
7414194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
74151a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
741647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
741747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
741847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
741947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
742047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
742147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
742247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
742347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
742447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
742547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
742647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
742747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
742847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
742947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
743047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
743147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
7432f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
7433f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
743447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
7435f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
7436f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
7437f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
743847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
7439194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
7440194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
7441194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
7442194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
7443194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
7444194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
7445194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
74464ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
7447194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
7448194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
7449194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
745047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
745147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
745247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
745314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbachstatic const char *getSubtargetFeatureName(unsigned Val);
7454fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
7455fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
7456fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7457fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
7458fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
74593a86e1396230748f17a521915bc802939a787eacChad Rosier  unsigned Kind;
74603a86e1396230748f17a521915bc802939a787eacChad Rosier  unsigned Opcode;
7461fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
746219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
74633a86e1396230748f17a521915bc802939a787eacChad Rosier
74643a86e1396230748f17a521915bc802939a787eacChad Rosier  MatchResult = MatchInstructionImpl(Operands, Kind, Opcode, Inst, ErrorInfo);
7465193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
746619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
7467e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
7468189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
7469189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
7470a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
7471a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
7472a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
7473a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
7474189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
7475a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
7476189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
7477f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
747883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
747983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
748083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
748183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
748283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
7483f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
7484a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
7485a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
7486a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
7487a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
7488a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
748974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
749074423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // doesn't actually encode.
749174423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    if (Inst.getOpcode() == ARM::ITasm)
749274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      return false;
749374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach
749442e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Inst.setLoc(IDLoc);
7495fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
7496fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
749714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  case Match_MissingFeature: {
749814ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    assert(ErrorInfo && "Unknown missing feature!");
749914ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    // Special case the error message for the very common case where only
750014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    // a single subtarget feature is missing (Thumb vs. ARM, e.g.).
750114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    std::string Msg = "instruction requires:";
750214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    unsigned Mask = 1;
750314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
750414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach      if (ErrorInfo & Mask) {
750514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach        Msg += " ";
750614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach        Msg += getSubtargetFeatureName(ErrorInfo & Mask);
750714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach      }
750814ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach      Mask <<= 1;
750914ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    }
751014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    return Error(IDLoc, Msg);
751114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  }
7512e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
7513e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
7514e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
7515e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
7516e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
751716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7518e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
7519e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
7520e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
752116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7522e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
7523e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
7524e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
7525362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer    return Error(IDLoc, "invalid instruction",
7526362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer                 ((ARMOperand*)Operands[0])->getLocRange());
7527f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
7528f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
752947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
753047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
7531194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
7532194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
7533194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
7534194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
753570c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach  case Match_ImmRange0_15: {
753670c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
753770c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
753870c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    return Error(ErrorLoc, "immediate operand must be in the range [0,15]");
753970c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach  }
7540fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
754116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7542c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
7543fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
7544fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
75451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
7546ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
7547ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
7548ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
75491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
7550515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
75511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
75529a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
75539a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
7554515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
75551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
7556515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
75571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
7558515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
75591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
7560a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
7561a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
7562d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".arch")
7563d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveArch(DirectiveID.getLoc());
7564d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".eabi_attribute")
7565d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveEabiAttr(DirectiveID.getLoc());
7566ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
7567ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7568ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
75691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
7570ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
75711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
7572ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
7573ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
7574ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
7575ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
7576ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
7577ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7578aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
7579ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7580ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
7581ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
758216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7583ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
7584ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
7585ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
7586b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
7587ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
7588ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
7589ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7590b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7591ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
7592ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7593ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
75941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
7595515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
75961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
7597515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
7598515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7599b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7600515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76019a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
76029a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
76039a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
76049a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
76059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
76069a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
76079a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
76089a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
76099a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
76109a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
76119a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
76129a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
76139a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
76149a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
76159a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
76169a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7617515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7618515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7619515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
7621515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
76221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
76236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
76246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
76256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
7626de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  bool needFuncName = true;
76276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7628de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Darwin asm has (optionally) function name after .thumb_func direction
76296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
76306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
76316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
7632de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    if (Tok.isNot(AsmToken::EndOfStatement)) {
7633de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
7634de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach        return Error(L, "unexpected token in .thumb_func directive");
7635de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Name = Tok.getIdentifier();
7636de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Parser.Lex(); // Consume the identifier token.
7637de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      needFuncName = false;
7638de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    }
76396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
76406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7641de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
7642515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7643de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach
7644de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Eat the end of statement and any blank lines that follow.
7645de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  while (getLexer().is(AsmToken::EndOfStatement))
7646de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    Parser.Lex();
7647515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
7649de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // We really should be checking the next symbol definition even if there's
7650de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // stuff in between.
7651de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (needFuncName) {
7652d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
76536469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
76546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7655642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
7656642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
7657642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
7658515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7659515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7660515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
7662515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
76631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
766418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
7666515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
766738e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
766858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
7669b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
767058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
76719e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
7672515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7673515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
7674515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7675515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
767618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7677b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7678515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
7680515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
7681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
7685515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
76861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
768718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7688515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
7689515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
769018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
769158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
7692b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
769358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
7694b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
7695515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7696515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
7697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7698515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
769918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7700b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
770232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
770398447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
7704ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
770598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
770632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
770798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
7708ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
770998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7710eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
77112a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
7712515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7713515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7715a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
7716a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
7717a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7718a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
7719a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
7720a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
7721a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
7722a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7723a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
7724a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7725a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7726a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
7727a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7728a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7729a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
7730a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
7731a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7732a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7733a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
7734a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7735a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
7736a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
7737a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
7738a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7739a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7740a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7741a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7742a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
7743a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
7744a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
7745a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
7746a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7747a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
7748a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7749a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
7750a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
7751a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7752a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7753a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7754d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch
7755d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .arch token
7756d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) {
7757d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7758d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7759d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
7760d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr
7761d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .eabi_attribute int, int
7762d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
7763d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7764d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7765d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
776690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
776790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
77689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
7769ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
777094b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
777194b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
777290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
7773ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
77743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
77750692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
77768030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper#define GET_SUBTARGET_FEATURE_NAME
77770692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
77783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
7779