ARMAsmParser.cpp revision 28f08c93e75d291695ea89b9004145103292e85b
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
85ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
86ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
87ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
900d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
999a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
103a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveReq(StringRef Name, SMLoc L);
104a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveUnreq(SMLoc L);
105d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveArch(SMLoc L);
106d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveEabiAttr(SMLoc L);
107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
11089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
112fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
115ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
116ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
117ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
118ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
119ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
120ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
12147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
12247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
124194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
125194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
126194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
127acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
128acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
129acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
13032869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
131ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
132ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
134acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
135acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
136acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
137ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1410692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
148f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
150f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1548bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1568bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1588bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
166f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
167c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
168580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
170293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
172251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1739d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
174862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
177ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
180a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
181a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
182eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
183eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
184ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
185ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
187ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1899ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
190548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
191548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
193ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1957b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
2052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
20714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
208623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
209623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
21088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
21188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
21212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
21312431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
21412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
21512431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
2164334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2174334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
2184334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2194334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
220189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
222189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
224f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
225d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
226d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
227189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
228ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
22947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
230194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
232194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
233194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
23547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
236ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
23794b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
238ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
23932869205052430f45d598fba25ab878d8b29da2dEvan Cheng
24028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    // Cache the MCRegisterInfo.
24128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    MRI = &getContext().getRegisterInfo();
24228f08c93e75d291695ea89b9004145103292e85bJim Grosbach
243ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
244ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
247f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
248ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
249ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
253189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
25647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
25747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
261ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
26216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
26316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2643a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
266a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
267a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
268146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
27821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
282460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
28421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
28621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
287862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
28898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
29121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
29221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
29321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
29421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
29521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
29924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
3038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
307fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
308fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
309fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
310fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
31589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
31689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
31989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
32089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
32189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
32289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
337a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
338a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
339862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
340862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
341862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
342862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3440aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
345862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
346862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3478155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
348460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
349460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
350460a90540b045c102012da2492999557e6840526Jim Grosbach
351460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
352cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
353cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
35416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3556a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
356a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
357a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
36357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
36457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
365eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
367e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
371f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
372f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
373f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
377580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
378e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
379580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
385af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
38692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
38792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
38892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
38992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
390af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
394293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
395293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
396293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
397293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
39916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
400146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
401146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
403762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
405762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
406762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
40721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
41021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
41189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
41289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
418762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
419762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
42221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
42324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
425862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
42698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4277636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
428862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
429862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
43121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
432fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
433fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
43721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
438762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
439762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
441706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
442706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
44321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
444e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
445762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
44921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
450584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
451584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
45221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
453a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
459af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
46121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
462af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
46392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
46721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
468293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
469293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
470460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
471460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
472460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
476762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
48221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4838462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
48721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
488fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
489fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
490fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
49221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
494a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
49721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4987729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
500a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
50221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
50424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5058d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
50821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    assert(isImm() && "Invalid access!");
509cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
510cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
511cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
512460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
513460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
514460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
515460a90540b045c102012da2492999557e6840526Jim Grosbach  }
516460a90540b045c102012da2492999557e6840526Jim Grosbach
517706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
51821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
519706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
521706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
52321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
527584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
52821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
529584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
531584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
53221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
53621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
53821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
54051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  bool isFPImm() const {
54151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!isImm()) return false;
54251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
54351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!CE) return false;
54451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
54551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    return Val != -1;
54651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  }
5474050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits16() const {
5484050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5494050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5504050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5514050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5524050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 0 && Value <= 16;
5534050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
5544050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits32() const {
5554050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5564050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5574050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5584050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5594050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 1 && Value <= 32;
5604050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
561a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
56221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
563a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
564a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
565a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
566a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
567a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
56872f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
56921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57072f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57172f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57272f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
57372f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
57472f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
57572f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
57621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57972f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
58072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
58172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
58321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
5846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
59021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
591587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
592587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
593587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
594587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
595587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
596587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
59721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
598587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
599587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
600587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
601587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
602587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
60421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
61121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
61283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
61383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
61483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
61583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
61683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
61821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6197c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6207c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6217c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6227c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6237c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
624730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
62521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
626730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
627730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
628730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
629730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
630730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
63221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6353b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
63921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6423b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
64621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6473b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6483b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6493b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6503b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6513b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
65321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6566b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
66021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6636b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
66721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
67421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6766b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6786b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
6796b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
68121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
68821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6913b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
69521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6973b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6983b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6993b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
7003b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
701f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
70221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
703f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
70921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7114a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
715ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
71621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
717ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
718ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
719ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
720ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
721ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
722fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
72321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
724fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
725fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
726fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
727fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
728fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
729ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
73021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
731ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
732ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
733ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
734ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
735ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
736ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
737ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
738ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
73921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
740ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
741ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
742ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
743ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
744ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
74570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
74621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
74770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
74870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
74970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
75070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
75170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
752f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
75321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
756f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
76021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7666bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
76721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7696bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
7706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
7716bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
7726bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
773e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
77421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
775e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
776e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
777e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
778e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
779e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
7803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
78121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7833bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
7843bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
7853bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getSOImmVal(-Value) != -1;
7863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
7876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
78821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
7916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
7926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
7936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
79489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
79521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
79689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
79789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
79889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
79989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
80089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
8013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
80221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8043bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8063bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getT2SOImmVal(-Value) != -1;
8073bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
80921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
811c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
812c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
813c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
814c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
81521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
81621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
81721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
81821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
81921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
82021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
82121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
82221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
82321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
82421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
82521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
82621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
82721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
828f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
829430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
830f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
83157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
832f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
833ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
83557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
83657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
83757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
8380b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  bool isMemPCRelImm12() const {
8390b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
8400b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8410b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base register must be PC.
8420b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum != ARM::PC)
8430b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8440b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Immediate offset in range [-4095, 4095].
8450b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!Memory.OffsetImm) return true;
8460b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8470b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8480b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
84957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
85057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
851ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
85357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
855e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
857e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
858e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
861039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
86221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
863039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
864039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
865039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
866039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
867039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
868039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
8692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
8702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
8712f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
8722f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
87321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
8742f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
87557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
877e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
8782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
881e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
882e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
8842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
88621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
88821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
8902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
894251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
895251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
8962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
898681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
899681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
900681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
90121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
902681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
90357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
905e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
907e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
908e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9090da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
910681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
913e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9167f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
919e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
92157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9227f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9237f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
92657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
927ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
928ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
930ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
93157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
93257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
933ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
934ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
935e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
937e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
938ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
939ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
940ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
944e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
94557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
94687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
947e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
948e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
94960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
95060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
951e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
95257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
95360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
95460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
955e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
956e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
957ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
958ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
95938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
960e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
96238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
96338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
964e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
965e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
96638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
96738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
96848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
969e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
97148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
97248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
973e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
974e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
97548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
97648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
977ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
97857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
980ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
981ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
982e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
983e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
984ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
985505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
986a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
9872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
9882f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
9892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
99021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
9912f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
99257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
995e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
996e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
997a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
998a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
999b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
100057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1001b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
1003e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1004e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1005b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1006b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
100857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1009f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10100b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10110b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1013e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1014e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10154d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1016f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1017f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
101857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1020f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1021e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1022e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1023f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1024f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1025a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
102657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1027a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
10280b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10290b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1031df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1032e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1033df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1035a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
103657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1037a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1038a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1039e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1040e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1041a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1042a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
104409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
104509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
104609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
104721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
104809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
104909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
105057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1051ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1053e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1054e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10550da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
105821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1060ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
10617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
106263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1063ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
106521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
10682bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
10692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
10702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
10712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
10727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
107321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
107421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
10753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
10770aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
10780aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
10790aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
10800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
10810aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
10820aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
10840aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1085862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1086862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1087862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1088280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  bool isVecListTwoD() const {
10890aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1090280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    return VectorList.Count == 2;
1091280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
1092280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
109328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  bool isVecListDPair() const {
109428f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!isSingleSpacedVectorList()) return false;
109528f08c93e75d291695ea89b9004145103292e85bJim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
109628f08c93e75d291695ea89b9004145103292e85bJim Grosbach              .contains(VectorList.RegNum));
109728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
109828f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1099cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
11000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1101cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1102cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1103cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1104b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
11050aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1106b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1107b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1108b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
11094661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  bool isVecListTwoQ() const {
11100aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11110aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return VectorList.Count == 2;
11124661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  }
11134661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach
1114c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  bool isVecListThreeQ() const {
1115c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
1116c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return VectorList.Count == 3;
1117c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
1118c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
11197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  bool isVecListFourQ() const {
11207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    return VectorList.Count == 4;
11227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  }
11237945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
11243471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isSingleSpacedVectorAllLanes() const {
11253471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
11263471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11273471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isDoubleSpacedVectorAllLanes() const {
11283471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
11293471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
113098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
11313471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
113298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
113398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
113498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
113513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  bool isVecListTwoDAllLanes() const {
11363471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11373471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return VectorList.Count == 2;
11383471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11393471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach
11403471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isVecListTwoQAllLanes() const {
11413471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
114213af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
114313af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
114413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeDAllLanes() const {
11465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
11505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeQAllLanes() const {
11515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
11525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
1155a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourDAllLanes() const {
1156a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1157a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1158a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1159a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
1160a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourQAllLanes() const {
1161a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
1162a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1163a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1164a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
116595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isSingleSpacedVectorIndexed() const {
116695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
116795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
116895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isDoubleSpacedVectorIndexed() const {
116995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
117095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
11717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
117295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
11747636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
11757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1176799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
117795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1178799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1179799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1180799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1181799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
118295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1183799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1184799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1185799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
11869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
118795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
11899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
11909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1191799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
119295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
119395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
119495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
119595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
119695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQWordIndexed() const {
119795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
119895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
119995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
120095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
120195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQHWordIndexed() const {
120295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1203799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1204799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1205799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1206799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
120795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1208799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1209799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1210799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12113a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDByteIndexed() const {
12123a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12133a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
12143a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12153a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12163a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDHWordIndexed() const {
12173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12183a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12193a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12203a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12213a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQWordIndexed() const {
12223a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12233a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12243a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12253a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12263a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQHWordIndexed() const {
12273a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12283a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12293a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDWordIndexed() const {
12323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
1236e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDByteIndexed() const {
1237e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1238e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1239e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1240e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1241e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDHWordIndexed() const {
1242e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1243e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1244e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1245e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1246e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQWordIndexed() const {
1247e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1248e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1249e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1250e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1251e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQHWordIndexed() const {
1252e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1253e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1254e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1255e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1256e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDWordIndexed() const {
1257e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1258e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1259e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1260e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1261460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1262460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1263460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1264460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1265460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1266460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1267460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1268460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1269460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1270460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1271460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1272460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1273460a90540b045c102012da2492999557e6840526Jim Grosbach
12740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
127521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12770e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
12780e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
12790e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
12800e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
12810e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
12820e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
12830e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1284460a90540b045c102012da2492999557e6840526Jim Grosbach
1285ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
128621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1287ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1288ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1289ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1290ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1291ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1292ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1293ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1294ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
12956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
129621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
12996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
13026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
13066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
13086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
130921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13166248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13176248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13186248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13196248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13206248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13216248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13226248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13239b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  bool isNEONi32vmovNeg() const {
132421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13259b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13269b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // Must be a constant.
13279b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (!CE) return false;
13289b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    int64_t Value = ~CE->getValue();
13299b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13309b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13319b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    return (Value >= 0 && Value < 256) ||
13329b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13339b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13349b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13359b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13369b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13379b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
13386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1339f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
134021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1341f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1342f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1343f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1344f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1345f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1346f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1347f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1348f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1349f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1350f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
13513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
135214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
135314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
135414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
135514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
13563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
13573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
13583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
13593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
13603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
13618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1362345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
13638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
136404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
136504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
13668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
13678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1371fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
13739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
13749b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
13769b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13779b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
13789b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
13799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
13819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
138389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
138489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
138589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
138689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
138789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
138889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
138989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
139089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
139189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
139289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1393d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1394d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1395d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1396d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1397d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1400a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1401a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1402a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1403af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1404e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1405430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1406430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1407af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1408af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1409e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1410af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1411e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1412e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1413af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1414152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1415430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1416430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1417af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
141892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1419af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
142092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
142192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1422580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
14230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1424580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1425580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
14260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
142887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
14297729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
14305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
14315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
14327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
14337729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
143487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
143587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
14360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
14370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
14410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14420f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14430f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
14457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
14477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
14487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1450293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1451293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1452293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1453293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1454293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1455293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1456293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1457293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1458293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1459293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1460293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
14613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
14626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
14646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
14656b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
14664050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits16Operands(MCInst &Inst, unsigned N) const {
14674050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14684050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14694050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
14704050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14714050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14724050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits32Operands(MCInst &Inst, unsigned N) const {
14734050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14744050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14754050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
14764050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14774050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14789d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
14799d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
148051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
148151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
148251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14839d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
14849d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1485a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1486a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1487a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1488a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1489a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1490a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1491a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1492a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
149372f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
149472f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
149572f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
149672f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
149772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
149872f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
149972f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
150072f39f8436848885176943b0ba985a7171145423Jim Grosbach
150172f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
150272f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
150372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
150472f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
150572f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
150672f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
150772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
150872f39f8436848885176943b0ba985a7171145423Jim Grosbach
1509f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1510f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1511f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1512f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1513f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1514f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1515f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1516f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
15174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
15184a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15194a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
15204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
15214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
15234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
15244a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
152570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
152670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
152770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
152870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
152970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
153070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
153170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1532ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1533ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1534f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1535f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1536f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1537f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1538f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1539f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1540f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1541f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1542f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
154389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
154489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
154589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
154689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
154789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
154889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
154989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
155089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
15513bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
15523bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15533bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
15543bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15553bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15563bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15573bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15583bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1559e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1560e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1561e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1562e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1563e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1564e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1565e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1566e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
15673bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
15683bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15693bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
15703bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15713bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15723bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15733bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15743bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1575706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1576706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1577706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1578706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1579706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
15807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
15817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1582e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1583505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1584505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
15850b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
15860b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15870b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int32_t Imm = Memory.OffsetImm->getValue();
15880b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // FIXME: Handle #-0
15890b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
15900b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
15910b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
15920b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach
159357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
159457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
159557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
159657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
159757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
159857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
15997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
16007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1601e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1602e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
16057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
16077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
16087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
16097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
16107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1611e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1612e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1614e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1615e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1619039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1620039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1621039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1622039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1623039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1624039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1625039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1626039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1627039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1628039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1629039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1630039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1631039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1632039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
16332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
16342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
16352f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
16362f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
16372f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
16382f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
16392f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
16402f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
16412f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
16422f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
16432f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
16442f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1645e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1646e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
16492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
16512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
16522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
16532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
16542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1655e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
16562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1657e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1658e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
16632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
166421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
16652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
16662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
16672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
16682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
16702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
16712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
16732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
16742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
16752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
16772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
16802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
16812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
16857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1686681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1687681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1688681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1689681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1690681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1691681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1692681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1693681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1694681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
16957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1696e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
16977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
16997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
17007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
17017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1702e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
17057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1706a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1707a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "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::CreateImm(0));
17142f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17152f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17162f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1717e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1718e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1719a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1720a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1721a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1722b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1723b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1724b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1725e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1726e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1727b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1728b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1729b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
17307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
17317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1732e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1733e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1735ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1736ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1737f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1738f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1739f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1740f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1741a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1742f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1743a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1744a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1745a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1746a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1747a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
174821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
1749a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1750a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1751a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1752a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1753a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1754a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1755e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1756e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1757a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1758a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1759a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
17607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
17617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
176209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
176321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
176409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
176509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
176609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
176709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
176809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
176909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1770e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1771e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
177492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
17757f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
17767f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1777e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1778e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17797f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17807f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
17827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1783e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1784e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17857f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17867f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
17887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1789430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1790430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1791430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1792e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1793e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1796d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1797ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1798ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1799e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1800e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1801e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1802ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1803ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
18047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
18057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1806e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1807e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
180814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
18093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
181060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
181160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1812e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1813e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
181460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
181548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
181648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
181738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
181838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1819e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1820e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
182138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
182238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
182338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
182448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
182548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1826e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1827e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
182848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
182960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
183060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1831ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1832ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1833e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1834e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1835ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1836ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1837ecd858968384be029574d845eb098d357049e02eJim Grosbach
18387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
18397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
18427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
18437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
184463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
18457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
18467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1847f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1848ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
18492bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
18502bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
18512bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18522bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
18532bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
18542bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
18552bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
18562bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
18572bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
18582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
18592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
18602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
18617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
18627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1864f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1865f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1866f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1867f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1868f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1869f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1870f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1871f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1872f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1873f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1874f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1875f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1876ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1877ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1878584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1879584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1880584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1881584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1882584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1883a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1884a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1885a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1886a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1887a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
18886029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1889862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1890862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1891862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1892862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
18937636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
18947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
18967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
18977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
18987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1899460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1900460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1901460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1902460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1903460a90540b045c102012da2492999557e6840526Jim Grosbach
1904460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1905460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1906460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1907460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1908460a90540b045c102012da2492999557e6840526Jim Grosbach
1909460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1910460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1911460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1912460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1913460a90540b045c102012da2492999557e6840526Jim Grosbach
19140e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
19150e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
19180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
19200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
19210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1922ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1923ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1924ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1925ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1926ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1927ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1928ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1929ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1930ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1931ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1932ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1933ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
19346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
19356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
19396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
19406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
19416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
19426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
19436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
19446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
19456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
19486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
19496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
19536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
19586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
19599b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19609b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
19619b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach
19629b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
19639b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19649b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19659b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19669b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    unsigned Value = ~CE->getValue();
19679b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19689b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19699b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19709b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19719b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffffff)
19729b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 24) | 0x600;
19736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1976f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1977f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1978f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1979f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1980f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1981f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1982f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1983f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1984f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1985f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1986f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1987f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1988b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1989b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
199089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
199121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
199289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
199389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
199489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
199589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
199689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
199789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
19983a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
199921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
2000345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
2001345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
2002345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
20033a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2004345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
2005345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2006fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
200721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
2008fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2009fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2010fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2011fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2012fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2013fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2014fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
201521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
2016fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2017fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2018fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2019fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2020fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2021fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
20229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
20239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
20249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
20259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
20269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
20279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
20289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
20299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2030d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
203121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
2032d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
2033d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
2034d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
2035d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
2036d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
2037d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
20383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
203921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
2040762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
2041762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
2042762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2043762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
20443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2045a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2046a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
204750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
204821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
2049762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
2050762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2051762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
20523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2053a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2054a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
2056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
2057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
2058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
2059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
206021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
2061af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
2062af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
2063af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
2064af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
2065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
2066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
2067e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
2068e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2069e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
207092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
207192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
207292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
207392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
207421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
2075af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
2076af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
2077af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
207892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
207992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
208092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
208192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
208292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
2083580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
20840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
208521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
2086580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
2087580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
20880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
20890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
20900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
20910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
20920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
20937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
209421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
20957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
20967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
20977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
20987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
20997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2101293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
2102293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
210321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
2104293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
2105293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
2106293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
2107293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
2108293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
2109293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2110293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
21117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
21125fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
2113cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
211421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
21150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
2116d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
211721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
2118d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2119275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
212021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
21210f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
21220f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
21235fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
21247729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
212524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
2126cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
2127cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
2128cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
21298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
21308d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
21318d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
2132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
21330aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
2134862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
2135862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
2136862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
21370aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2138862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
2139862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
2140862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
2141862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2142862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
214398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
21443471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                              bool isDoubleSpaced,
214598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
214698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
214798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
214898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
21493471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
215098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
215198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
215298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
215398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
215498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
21557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
215695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             unsigned Index,
215795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             bool isDoubleSpaced,
215895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             SMLoc S, SMLoc E) {
21597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
21607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
21617636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
21627636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
216395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
21647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
21657636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
21667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
21677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
21687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
2169460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
2170460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
2171460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
2172460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
2173460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
2174460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
2175460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
2176460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2177460a90540b045c102012da2492999557e6840526Jim Grosbach
21783a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
217921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
2180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
2181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2182762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2184cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2185cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
21867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
21877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
21887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
21897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
21900d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
219157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
21927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
21933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
219421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2195e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2196e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2197e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2198e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2199e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
220057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2201e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
22027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
22037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
22047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
22057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
220616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2207f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2208f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2209f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
22107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
221121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
22127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2213f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2214f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2215f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2216762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2217762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2220706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2221706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
222221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2223706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2224706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2225706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2226706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2227706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2229a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
223021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2231a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2232a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2233a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2234a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2235a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
223821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2242584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2246a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2248b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2249fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
225021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
22516a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2252fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
225321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2254d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2255d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
225621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
22571a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    static const char *MaskStr[] = {
22581a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
22591a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
22601a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
226189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
226289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
226389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
226489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
226521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2266fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2267fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
226821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2269fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
22719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
22729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
22739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
227421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
227721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2278fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2279fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
228021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2281706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
228321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
22846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2285e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
22866ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2287fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
228821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2289f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2290f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2291f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2292f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2293f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2294f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
22957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
229621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2297a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2298a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2299a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2302a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2304a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
230521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
230650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2307fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
230821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2309580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2310580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2311e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
231221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
231392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2314efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2315efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2316efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
23170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
231821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
231992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2320efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2321efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2322efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
232392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
232421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
23257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
23267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
232721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2328293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2329293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2330293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
233121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
233221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
233321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
23348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
23358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
23365fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
23375fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
23387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
23397729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
23407729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
23418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
23428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
23438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
23448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
23458d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2346862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2347862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2348862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2349862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
235098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
235198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
235298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
235398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
23547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
23557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
23567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
23577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
235821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2359fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2360fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2361460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2362460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2363460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2364fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2365fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
23663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
23683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
23693483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
23713483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23723483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
23733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
237469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
237569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2376a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
23771355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2378a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2379bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2380bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2381bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2382bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
23839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2384e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2385e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
23863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
23871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
238818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
23897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2390d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2391590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
23920c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
23930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
23940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
23950c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
23960c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
23970c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
23980c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
239940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
240040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
240140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
240240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
240340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
240440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
240540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
240640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
240740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
240840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
240940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
241040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
241140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
241240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
241340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
241440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
24150c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
24160c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2417a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2418aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // Check for aliases registered via .req. Canonicalize to lower case.
2419aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // That's more consistent since register names are case insensitive, and
2420aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // it's how the original entry was passed in from MC/MCParser/AsmParser.
2421aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
2422a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2423a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2424a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2425a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2426a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2427a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
242869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2429b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2430460a90540b045c102012da2492999557e6840526Jim Grosbach
2431e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2432e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2433d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
243419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
243519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
243619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
243719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
243819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
24390d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
24400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
24420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
24430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
24440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2445590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
24460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2447af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
24480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
24490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
24500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
24510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
24520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
24530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
24540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
24550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
245619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
24570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2458e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2459e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2461e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2463eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2464e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2465e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2466e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2467e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2468e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2469e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2470e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2471e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2472e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2473e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2474e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2475e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
24768a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
24778a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2478e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2479e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2480e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
248119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
248219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
248319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
248419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2485e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2486e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
248719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
248819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
248919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
249019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2491e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2492e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2493e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2494e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2495e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2496e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2497e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
249819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
249919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2500e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2501de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // shift by zero is a nop. Always send it through as lsl.
2502de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // ('as' compatibility)
2503de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      if (Imm == 0)
2504de626ad8726677328e10dbdc15011254214437d7Jim Grosbach        ShiftTy = ARM_AM::lsl;
2505e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
25061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2507e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
250819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
250919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
251019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
251119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
251219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
251319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2514e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
251519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
251619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2517e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2518e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
251992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
252092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2521af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
25220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
252392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
252492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
252592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
25260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
252719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
25280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
25290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
25300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
253150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
253250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
253350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2534e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2535e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2536e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
253750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
25381355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2539e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
25401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2541e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
254250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2543d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
254450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2546e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2547e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
254850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
254950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2550e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2551460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2552460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2553460a90540b045c102012da2492999557e6840526Jim Grosbach
2554460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2555460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2556460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2557460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2558460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2559460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2560460a90540b045c102012da2492999557e6840526Jim Grosbach
2561460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2562460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
256324dda217052b48373ed89d043a778aabb2f65080Jim Grosbach      return true;
2564460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2565ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (!MCE)
2566ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return TokError("immediate value expected for vector index");
2567460a90540b045c102012da2492999557e6840526Jim Grosbach
2568460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2569ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
2570ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return Error(E, "']' expected");
2571460a90540b045c102012da2492999557e6840526Jim Grosbach
2572460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2573460a90540b045c102012da2492999557e6840526Jim Grosbach
2574460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2575460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2576460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
257799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
257899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
257950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2580a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2582fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2583fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2584fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2585fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2586e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2587e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2588e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
25894d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default: return -1;
2590e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2591fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2592e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2593e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2594e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2595e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2596e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2597e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2598e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2599e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2602e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2603e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2604e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2605e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2606e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2607fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2608e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2610e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2611e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2612e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2613e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2614e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2615e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2616e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2617e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2618e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2619e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2620e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
262189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
262289df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
262389df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
262489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
262589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
262689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
262789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
262889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
262989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
263089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
263189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
263289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
263389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
263489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
263589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
263689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
263789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
263889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
263989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
264089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
264189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
264289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
264389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
264489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
264589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
264689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
264789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
264889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
264989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
265089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
265189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
265289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
265389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
265489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
265589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
265643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2657fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2658fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2659f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
266043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2661e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2662e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2663c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2664c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2665e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2666fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2667e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2668f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2669e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2670e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2671fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2672f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2673fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2674fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
267543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2676fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2677fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2678f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
267943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2680fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2681fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2682c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2683c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2684fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2685fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2686fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2687f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2688fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2689fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2690fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2691f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2692e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2693e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
26949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
26959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
26969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
26979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
26999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
27019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
27029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
27039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
27049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
27069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
27079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
27089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
27099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
27129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
27139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
27149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
27179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
27199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
27209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
27229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
27239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
27259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
27269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
27279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2728d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2729d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2730d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2731d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2732d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2733d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2734d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2735d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2736d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2737d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2738bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid GPR number!");
2739d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2740d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2741d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2742d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2743d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2744d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2745d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2746d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2747d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2748d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2749d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2750ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2751ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2752ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2753ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2754ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2755ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2756ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2757ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2758ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2759ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2760ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2761ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2762ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
276325e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2764ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2765ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2766ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2767ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2768ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2769ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2770ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2771ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2772ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2773d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
277450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
27751355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
277618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2777a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2778e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2779d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2780d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
278116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2782d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2783d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2784d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2785d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2786d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2787d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2788ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2789ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2790ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2791ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2792ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2793ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2794ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2795ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2796ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2797ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
27981a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2799d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2800d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2801d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2802d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2803d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2804d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2805d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2806d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2807e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2808ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2811d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2812d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2813d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2814d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2815d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2816d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2817e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2818d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2819d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2820d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2821d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2822ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2823ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2824ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2825d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2826d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2827d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2828d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2829d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2830d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2831d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2832d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2833d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2834d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2835d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2836d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2837d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2838d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2839d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2840d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2841d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2842d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2843d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2844d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2845d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2846a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2847d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2848d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
28492d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2850ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2851ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2852ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2853ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2854ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2855ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2856d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2857d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2858d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2859d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2860a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg))
2861d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2862a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) {
2863a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2864a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2865a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2866a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2867d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2868d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2869d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2870d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2871d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2872d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2873d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2874ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2875ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2876d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2877d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2878d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2879d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2880d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2881d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2882e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
288327debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
288450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
288527debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
288627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
288727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
288827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
288927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
289027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
289127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
289250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2893d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2894d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
289598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
289698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
28977636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
28987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
289998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
290098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
290198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
290298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
290398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
290498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
290598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
290698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2907c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCExpr *LaneIndex;
2908c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    SMLoc Loc = Parser.getTok().getLoc();
2909c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (getParser().ParseExpression(LaneIndex)) {
2910c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "illegal expression");
2911c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
29127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
2913c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
2914c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (!CE) {
2915c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "lane index must be empty or an integer");
2916c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2917c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2918c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2919c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "']' expected");
2920c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2921c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2922c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Parser.Lex(); // Eat the ']'.
2923c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    int64_t Val = CE->getValue();
2924c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach
2925c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    // FIXME: Make this range check context sensitive for .8, .16, .32.
2926c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Val < 0 || Val > 7) {
2927c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "lane index out of range");
2928c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2929c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2930c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Index = Val;
2931c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    LaneKind = IndexedLane;
2932c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    return MatchOperand_Success;
293398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
293498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
293598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
293698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
293798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
2938862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2939862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2940862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
294198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
29427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
29435c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
29445c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
29455c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
29465c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
29475c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
29485c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
29495c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
29505c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
29515c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
29525c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
29537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
295498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
295598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
295698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
295798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
295898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29590aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
296098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
296198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
296298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29633471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
29643471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
296598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
296895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
296995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29707636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
297198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
29725c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
29735c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
29745c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
29755c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
29767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
297798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
297898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
297998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
298098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
298198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
298228f08c93e75d291695ea89b9004145103292e85bJim Grosbach        // VLD1 wants a DPair register.
298328f08c93e75d291695ea89b9004145103292e85bJim Grosbach        // FIXME: Make the rest of the two-reg instructions want the same
298428f08c93e75d291695ea89b9004145103292e85bJim Grosbach        // thing.
298528f08c93e75d291695ea89b9004145103292e85bJim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
298628f08c93e75d291695ea89b9004145103292e85bJim Grosbach                                      &ARMMCRegisterClasses[ARM::DPairRegClassID]);
298728f08c93e75d291695ea89b9004145103292e85bJim Grosbach
29880aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
298998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
299098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
299198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29923471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
29933471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
299498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
299795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
299895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
300098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
30015c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
30025c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
30035c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
30045c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
30055c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
30065c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
30075c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
3008862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
3009862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3010862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
3011862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
3012862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3013862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
3014862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
3015862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
3016862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3017862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3018862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
3019276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
3020c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
3021c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
3022c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
3023c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
3024c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
30250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
30260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
3027c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
3028c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
3029c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
30307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
303198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
3032c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
3033e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
3034e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
3035e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
30360aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30370aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
30380aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
30390aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
30400aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
30410aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
30420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3043e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
3044e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
3045e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
3046e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
3047e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
3048e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3049e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3050e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
3051e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
3052e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
3053e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
3054e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
3055e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
3056e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
3057e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
3058e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
3059e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
3060e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3061e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3062e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
3063e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
3064e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
3065e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3066e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
306798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
306898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
30697636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
30707636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
307198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
30727636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
307398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
307498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
307598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
307698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
3077e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
3078e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
3079e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
3080e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
3081e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
3082e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
3083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
3084862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
3085862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
3086862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
3087862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
3088862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
3089862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3090862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3091c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
3092862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
3093862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
3094c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
3095c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
3096c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
3097c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
30980aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30990aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
31000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
31010aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
31020aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
31030aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
31040aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3105c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
3106c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
3107c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
3108c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
3109c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
3110c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
3111c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
311298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
311398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
31147636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
311598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
31167636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
311798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
31187636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
311998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
312098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
312198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
3122c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
3123c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
31240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
31250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
31260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
31270aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
31280aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
31290aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
31300aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
31310aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
3132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
3133862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3134862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3135862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
313698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
313798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
31387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
313998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
31407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
314198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
31427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
314398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
314498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
314598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
3146862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3147862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3148862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3149862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
3150862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
3151862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3152862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3153862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
3154862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
315598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
315698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
315728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (Count == 2 && Spacing == 1)
315828f08c93e75d291695ea89b9004145103292e85bJim Grosbach      // VLD1 wants a DPair register.
315928f08c93e75d291695ea89b9004145103292e85bJim Grosbach      // FIXME: Make the rest of the two-reg instructions want the same
316028f08c93e75d291695ea89b9004145103292e85bJim Grosbach      // thing.
316128f08c93e75d291695ea89b9004145103292e85bJim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0,
316228f08c93e75d291695ea89b9004145103292e85bJim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
316328f08c93e75d291695ea89b9004145103292e85bJim Grosbach
316428f08c93e75d291695ea89b9004145103292e85bJim Grosbach
31650aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
31660aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
316798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
316898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
316998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
31703471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                            (Spacing == 2),
317198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
317298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
31737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
31747636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
317595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           LaneIndex,
317695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           (Spacing == 2),
317795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           S, E));
31787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
317998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
3180862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
3181862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
3182862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
318343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
3184f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
318543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3186706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3187706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3188706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
3190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
3192706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
3193706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
3194032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
3195706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
3196032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
3197706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
3198706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
3199032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
3200706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
3201032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
3202706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
3203706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
3204706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
3205706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3206706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
3207f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
3208706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3209706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3210706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3211f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3212706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3213706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
321443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3215a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
321643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3217a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3218a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3219a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3220a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3221a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
32222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
32232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3224a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
32252dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
32262dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
32272dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
32282dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
32292dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
32302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
32312dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
32322dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
32332dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
32342dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
32352dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
32362dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
32372dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
32382dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
32392dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3240a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3241a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3242a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3243a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3244a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3245584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3246584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
324743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
324943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3252584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3254584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3255acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3256acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3257acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
3258acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
3259acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
3260acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
3261acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
3262acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
3263acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
3264acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
3265acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
3266acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
3267acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
3268acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
3269acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
3270acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
3271acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
3272acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
327318c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3274acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3275acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3276acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3277acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
3278acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3279acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
328018c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3281acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3282acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3283acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3284acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3285acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3289590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3290584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3300b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
33054b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3309bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
33104b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
331256926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
331356926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
33317784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
33327784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
33337784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
33347784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
33357784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
33367784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
33377784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3340584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3341584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3342584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3343584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3344584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3345584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3346a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3347a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3348f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3349f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3350f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3351f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3352f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3353f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3354f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3355f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3356f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3357590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3358590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3359f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3360f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3361f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3362f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
33668a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33678a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3372f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3373f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3374f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3375f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3376f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3377f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3378f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3379f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3380f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3381f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3382f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3383f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3384f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3385f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3386f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3387f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3388f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3389f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3390f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3391f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3392f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3393f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3394f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3395c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3396c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3397c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3398c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3399c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3400c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3401c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3402c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3403c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3404c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3405c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3406c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3407c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3408c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3409c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3410c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3411c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3412c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3413c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3414c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3415c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3416c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3417c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3418c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3419580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3420580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3421580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3422580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3423580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3424580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3425580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3426580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3427580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3428580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3429580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3430580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3431580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3432580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3434580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3440580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3441580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3442580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3444580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
34458a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
34468a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3447580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3448580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3449580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3450580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3451580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3453580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3454580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3455580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3457580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3459580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3461580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3462580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3464580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3466580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3467580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3468580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3469580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3470580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
34710afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
34720afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
34730afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
34740afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
34750afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3476580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3477580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3478580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3479580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3480580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3481580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3482580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3483580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3484580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3485580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3486580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3487580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3488580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3489580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3490580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
34917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
34927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
34937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
34947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
34957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
34967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
34977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3498326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3499326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
35007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3501326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3502326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
35037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
35047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
35068a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35078a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
35087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
35097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
35127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
35147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
35157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
35167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
35177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
35207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
35217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
35227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
35267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
35277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
35287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
35297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
35307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
35317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
35357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
35367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
35387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
35397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3540293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3541293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3542293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3543293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
35448a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35458a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3546293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3547293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3548293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3549293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3550293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3551293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3552293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3553293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3554293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3555293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3556293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3557293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3558293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3559293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3560293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3561293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3562293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3563293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3565293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3567293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3568293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3569293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3570293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3571293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3572293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3573293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3574293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3575293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3576293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
35778a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35788a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3580293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3581293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3582293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3583293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3584293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3585293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3586293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3587293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3588293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3589293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3590293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3591293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3592293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3593293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3594293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3595293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3596293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3597293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3598293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3599293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3600293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3601293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3602293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3603293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3604293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3605293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3606293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3607293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
36087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
36097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3611f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3612f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3613f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
36147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
36157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
36167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
36177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
36187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
36197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
36207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
362116578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
36227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
36237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
36247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
36257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
36267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
362816578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
36297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
36307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
36317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
36327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
36337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
36347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
36357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
36367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
36377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
36387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
36397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
36407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3641f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3642f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
36430d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
36440d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
36450d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
36460d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
36470d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3648f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3649f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3650f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
36517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
36527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
36537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
36547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3655251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3656251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3657251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3658251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3659251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3660251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3661251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3662251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3663251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3667251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3668251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3670251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3671251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
36728a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
36738a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3674251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3675251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3678251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3680251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3681251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3682251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3683251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3684251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3685251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3686251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3687251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3688251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3689251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3690251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3691251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3692251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3693251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3694251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3695251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3696251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3699251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3700251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3701251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3702251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3703251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3704251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3705251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3706251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3707251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3708251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3709251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3710251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3711251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3712251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3713251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3714251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3715251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3716251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3717251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3718251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3719251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3720251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3721251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3722251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3723251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3724251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3725251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3726a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3727a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3728a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3729a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3730a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3731a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3732a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3733a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3734a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3737a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3738a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3739a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3740a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3741a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3742a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3743a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3744a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3745a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3746a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3747a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3748a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3749a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3750a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3751a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3752a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3753a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3754a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3755a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3756a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3757a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3758a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3759a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3760a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3761a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3762eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3763eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3764eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3765eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3766eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3767eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3768eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3769eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3770eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3771eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3772eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3773eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3774eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3775eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3776eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3777eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3778ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3779ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3780ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3781ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3782ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3783ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3784ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3785ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3786ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3787ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3788ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3789ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3790ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3791ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
37921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3793ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3794ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3795ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
37961355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3797ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3798ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3799ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3800ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3801ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3802ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3804ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3805ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3806ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3807ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38089ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
38099ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38109ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
38119ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
38129ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
38139ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38149ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38159ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38169ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
38179ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
38189ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38199ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
38209ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38219ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
38229ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
38239ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38249ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3825548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3826548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3827548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3828548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3829548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3830548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3831548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3832548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3833548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3834548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3835548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3836548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3837548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3838548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
38391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3840ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3841ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3842ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
38431355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3844ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3845ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3846ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3847548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3848548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3849548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
38517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
38527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
38537b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
38547b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38557b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
38567b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
38577b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
38587b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38597b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
38607b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38617b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38627b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
38637b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38647b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
38657b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
38667b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
38677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
38687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
38707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
38717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
38727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3874ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
38767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
38817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3882ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3883ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3884ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3885ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3887ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3888ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3889ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
38907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
38917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3893aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3894ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3895ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
38967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
39007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
39017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
39037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3904aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
39057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
39067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
39087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
39097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
39107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
39127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
39137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
39147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
39167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
39177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
39187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
39197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3920ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3921ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3922ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3923ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
39247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3925ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3926ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3927ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
39287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
39297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
39327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3933ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
39357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
39367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
39377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
39387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3939ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3940ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3941ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3942ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
39432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
39442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
39462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
39472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
39482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
39502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
39522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
39532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
39542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
39552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
39562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
39572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
39592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
39602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
396114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
396214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
396314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
396414605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
396514605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
396614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
396714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
396814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
396914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
397014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
397114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
397214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
397314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
397414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
397514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
397614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
397714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
397814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3979623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3980623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3981623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3982623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3983623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3984623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3985623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3986623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3987623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3988623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3989623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3990623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
3991623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
3992623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
399388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
399488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
399588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
399688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
399788ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
399888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
399988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
400088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
400188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
40027a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
40037a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
40047a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
40057a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
400688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
40077a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
400888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
400988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
401088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
401188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
40121b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
40131b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
40141b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
40151b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
40161b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
40171b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
40181b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
40191b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
40201b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
402188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
402288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
402388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
402488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
4025623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
402612431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
402712431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
402812431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
402912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
40306029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
403112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
403212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
403312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
403412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
403512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
403612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
403712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
403812431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
403912431329d617064d6e72dd040a58c1635cc261abJim Grosbach
404012431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
404112431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
404212431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
404312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
40446029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
404512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
404612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
404712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
404812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
404912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
405012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
405112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
405212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
405312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
405412431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
405512431329d617064d6e72dd040a58c1635cc261abJim Grosbach
40564334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
40574334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
40584334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40594334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
40604334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40614334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40624334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40634334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40646029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40654334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40664334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40674334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40684334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40694334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
40704334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
40714334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
40724334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40734334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
40744334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40754334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40764334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40774334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
40784334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
40794334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40806029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40824334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40834334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4086e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
40879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
408850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
40897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4090762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
409118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4092a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
4093762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
4094b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
4095a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
409618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
40971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
40987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
40997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
4100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41010571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
41020571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
41030571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
41047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
41050571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
41067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
4107762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
4108b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
4109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
411157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
411203f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
4113fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
4114fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
4115fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
4116fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4117fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
4118fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
4119fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
41207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
41217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
412250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
41237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
41247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
412550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
412657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
412757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
412857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
412957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
413057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
413157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
413257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
413357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
413457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
413557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
413657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
413757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
413857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
413957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
414057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
414157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
414257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
414357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
414457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
4145eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
4146eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4147eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
4148eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
414957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
415057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
415157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
415257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
415357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
415457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
415557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
415657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
415757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
415857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
415957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
416057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
416157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
416257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
416357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
416457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
416557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
416657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
416757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
416857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
416957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
417057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
417157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
417257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
417357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
417457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
417557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
417657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
41776cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
41786cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
41796cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
41808a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
41816cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
41828a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
41836cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
41847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
418550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
41860da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
41877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
41887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
41897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
419005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
41917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
41927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
41937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
41947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
41957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
41967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
41977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41980da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
41990da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
42000da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
42010da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
42020da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
42037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
42047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
42057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
42067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
42077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
420805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
42097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
42107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
42117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
421257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
421357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
42167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
42177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
42187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
42197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4220762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
42217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
42239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4224d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
42257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
42267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
42277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
42287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
42297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
42307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
42317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
42327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
42337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
42349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
42367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
42377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
42387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
42397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
42417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
42420d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
42437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
42447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
42450d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
42467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
42479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
424816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
42497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
42507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
42517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
42527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
42537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
42547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
425657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
42577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
42587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4259f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4260f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4261f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4262f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4263f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4264f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
42659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
42679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
42689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4270a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4271a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
42727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
42737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
42747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
42757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
427618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
427938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4280af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4281af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
42820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
42840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4285a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
42860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4287a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
42880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4289a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
42900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
42927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4293b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
42967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
42977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
42987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
42997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
43007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
43018a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
43028a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
43037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
43047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
43059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
43077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
43087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
43097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
43107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
43117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
43127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
43137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
43147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
43157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
43167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
43177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
43187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
43197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
43207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
43217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43269d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
43279d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
43289d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
432951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Anything that can accept a floating point constant as an operand
433051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // needs to go through here, as the regular ParseExpression is
433151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // integer only.
433251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  //
433351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // This routine still creates a generic Immediate operand, containing
433451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // a bitcast of the 64-bit floating point value. The various operands
433551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // that accept floats can check whether the value is valid for them
433651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // via the standard is*() predicates.
433751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
43389d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
43399d39036f62674606565217a10db28171b9594bc7Jim Grosbach
43408a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
43418a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
43429d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
43430e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
43440e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
43450e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
43460e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
43470e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
43480e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
43490e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
43500e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
43510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
43520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
43530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
43540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
43550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
43560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
43570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
43580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
43599d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
43609d39036f62674606565217a10db28171b9594bc7Jim Grosbach
43619d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
43629d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
43639d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
43649d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
43659d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
43669d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
43679d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
4368ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  SMLoc Loc = Tok.getLoc();
43699d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
437051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
43719d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
43729d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
437351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    IntVal ^= (uint64_t)isNegative << 31;
43749d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
437551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
437651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          MCConstantExpr::Create(IntVal, getContext()),
437751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          S, Parser.getTok().getLoc()));
43789d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43799d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
438051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Also handle plain integers. Instructions which allow floating point
438151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // immediates also allow a raw encoded 8-bit value.
43829d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
43839d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
43849d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
43859d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
4386ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach      Error(Loc, "encoded floating point value out of range");
43879d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
43889d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
438951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    double RealVal = ARM_AM::getFPImmFloat(Val);
439051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
439151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
439251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        MCConstantExpr::Create(Val, getContext()), S,
439351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        Parser.getTok().getLoc()));
43949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43959d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
43969d39036f62674606565217a10db28171b9594bc7Jim Grosbach
4397ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  Error(Loc, "invalid floating point immediate");
43989d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
43999d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
440051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
44019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
44029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
44031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4404fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4405762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4406fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4407fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4408fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4409f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4410f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4412f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4413f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4414f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4415f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4416f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4417fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4418a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4419146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4420146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
442150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
442219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
44231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
442450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
44250d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
442619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
44270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
442819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
442919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
44303cbe43fe69680df772d83947ced97ca445861213Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
44315cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
44325cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
44335cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
44345cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
44355cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
44365cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4437e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4438e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4439e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
444019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4441758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
444267b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
44436284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
444467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4445515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4446515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4447515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4448762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4449515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
445050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4451762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
445250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
445350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
445450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
44561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4457d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
44581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
44598a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
446063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4461079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4462079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
4463762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4464b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
446563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
4466515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
4467515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
446850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
446963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4470ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach    if (CE) {
4471ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      int32_t Val = CE->getValue();
4472ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      if (isNegative && Val == 0)
4473ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach        ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
447463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
447650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
447750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
447863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
44799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
44809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
44817597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
44827597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
44837597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
44841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
44859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44877597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
44887597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
44899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44917597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
44927597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
44939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
44947597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
44959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
44969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4498a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
45001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
45017597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
45021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
45037597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
45049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
45068a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
45079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
45089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
45109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
45119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
45159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
45167597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
45179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
45187597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
45199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
45209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
45219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
45249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
45269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
45279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
45309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
45319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
45329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4533352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4534352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4535352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4536badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
453789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
45381355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
45395f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
45405f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
454189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
454289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4543352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4544352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4545a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4546352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4547badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4548352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4549352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
45505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
45515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
45525f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
45535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
45545f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
45555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
45565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
45576849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
45586849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "fmuls")
4559352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4560badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
45613f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
45623f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4563ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
456471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
456504d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
45662f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
45673f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
45683f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
45693f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
45703f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
45713f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
45723f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
45733f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
45743f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
45753f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
45763f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
45773f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
45783f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
45793f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
45803f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
45813f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
45823f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
45833f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
45843f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
45853f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
45863f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
45873f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
45883f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
45893f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
459052925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4591345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4592352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4593352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4594352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
459500f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
45965f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
45975f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
45985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
459967ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
460048171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
46019c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach        Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
46021aa149f5acea364aa8bc9cfc3a167f78eff2e96bJim Grosbach        Mnemonic == "fmuls" || Mnemonic == "fcmps" ||
4603e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4604352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4605352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4606352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4607352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4608a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4609a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4610a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4611a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4612a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4613a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4614a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4615a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4616a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4617a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4618a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4619a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4620a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4621a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4622a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
462389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
462489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
462589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
462689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
462789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
462889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4629352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4630352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
46313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
46323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
46333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
46343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
46353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4636fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
46371355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4638fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4639eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4640eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
46413443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4642eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4643d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4644eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4645d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
46463443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4647d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4648d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4649eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4650fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4651eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
46523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4653eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4654eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4655eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4656eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4657ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4658ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
46590780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
46602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
46612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
46622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
46634af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
46644af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
46651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
46663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4667fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
46683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4669fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4670fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4671fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
467263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4673fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4674fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4675badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4676badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4677d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4678d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
467920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
468020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4681d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4682d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4683d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4684d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4685d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4686d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4687d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4688d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4689d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
46908adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4691d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4692d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4693d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4694d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
46953912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
46963912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
46973912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
46983912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
46993912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
47003912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
47013912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
47023912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
470372f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
470420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
470520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
470620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4707f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4708f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4709f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
471072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
471172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
471272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
471320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
471420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
471520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
471672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4717f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4718f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
471920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
472020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
472120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4722f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4723f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
472420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
472520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
472620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
472720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
472820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
472920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
473020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
473112a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // check against T3. If the second register is the PC, this is an
473212a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // alternate form of ADR, which uses encoding T4, so check for that too.
473320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
473420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
473512a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC &&
473620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
473720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
473820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
473920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
474020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
474164944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
474220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
474320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
474420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
474520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
474620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
474720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
474820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
474920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
475020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
475164944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
475264944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
475364944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
475464944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
475564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
475664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
475764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
475864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
475964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
476064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
476164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
476264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
476364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
476464944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47651de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
476664944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
476764944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
476864944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
476964944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
477064944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
477164944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
477264944f48a1164c02c15ca423a53919682a89074cJim Grosbach
47737f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
47747f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
47757f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
47767f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
47777f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
47787f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
47797f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
47807f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
47817f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
47827f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
47837f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47847f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
47857f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
47867f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
478764944f48a1164c02c15ca423a53919682a89074cJim Grosbach
478820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4789f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4790f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4791f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4792f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4793f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4794f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4795f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
479672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
479772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
479872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
479972f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
48003912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4801d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4802d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4803d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
48047aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
48057aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
48067aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
48077aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
48087aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
48097aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
48107aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
48117aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
48127aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
48137aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
48147aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
48157aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
48167aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
48177aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
48187aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
48197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
482021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4821badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4822badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4823badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
482421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
482521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
482621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
482721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
482821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
482921d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
483021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
483121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4832a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4833a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4834a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4835a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4836a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4837a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4838a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4839a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4840a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4841badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4842badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4843ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4844badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4845352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4846352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4848352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
484989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
48501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
485189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4852badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
48530c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
48540c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
48550c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
48560c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
48570c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
48580c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4859ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4860ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
486189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
486289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
486389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
486489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
486589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
486689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4867f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4868f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4869f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4870f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4871f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
487289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
487389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
487489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
487589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
487689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4877f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
487889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
487989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
488089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
488189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
488289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4883f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
488489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
488589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4886ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4887ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
48889717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
48893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
48903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
48913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
48923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
48933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
48943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
48953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
48963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
48971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
48983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
489933c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
490033c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
490133c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
490233c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4903ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
490433c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
490533c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4906c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4907c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4908c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4909c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4910c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4911c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4912c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
491333c16a27370939de39679245c3dff72383c210bdJim Grosbach
49143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4915f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4916f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
49173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4918f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4919f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
49203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
49213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
49223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4923f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4924f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
49253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4926f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4927badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4928345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4929a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4930a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4931a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4932a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4933a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4934a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4935a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4936345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
49375747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
49385747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
49395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4940a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4941a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
49427aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
49437aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
49447aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
49457aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
49467aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
49477aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
494881d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
494981d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
495081d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
495181d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
49525747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
49535747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
49545747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
49555747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4956a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
49571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4958cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4959cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4960cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4961a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4962a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4963b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4964a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
49661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4967cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4968cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4969cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4970a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4971a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
497216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4973cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4974186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4975cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4976186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4977cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4978146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
497934e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4980ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4981d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4982d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4983d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
498420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
498520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
498620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
498720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
498820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4989ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4990ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
4991ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
4992ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
4993ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4994cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
4995cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
4996cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
499721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
499821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
4999cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
5000cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
5001cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5002cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
5003cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
5004cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
5005857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
5006857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
5007857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
5008857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
5009857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
5010857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
5011857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5012857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5013857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
5014857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
5015857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
5016857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
501768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
501868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
501968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
502068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
502168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
502268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
502368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
502468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
502568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
502668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
502768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5028857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
5029857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
5030857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
5031934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
503255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
503355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
5034934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
503555b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
503655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
5037934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5038934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5039934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
504055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
504155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
5042d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
5043d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
5044d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
504555b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
5046d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
5047934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
5048934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5049934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
5050934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
5051934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
5052934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
50539898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
5054ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5055ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5056189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
5057aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
5058aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
5059aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
5060aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
5061aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
5062aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
5063aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
5064aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
5065aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
5066aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
5067aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
5068aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
5069aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
5070aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
5071aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
5072aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
5073aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
5074aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
507576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
507676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
507776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
507876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
507976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
508076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
508176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
508276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
508376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
508476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
508576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
5086f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
5087f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
5088f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
5089f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
50901a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5091f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
50921a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
5093f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
5094f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
5095f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5096189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
5097189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
5098189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
5099189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
51001a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
5101f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
5102f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
510374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // NOTE: BKPT instruction has the interesting property of being
510474423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // allowed in IT blocks, but not being predicable.  It just always
5105b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
510674423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT &&
510774423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      Inst.getOpcode() != ARM::BKPT) {
5108f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
5109f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
5110f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
5111f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
5112a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
5113f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
5114f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
5115f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
5116f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
5117f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
5118f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
5119f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
5120f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
5121f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
5122f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
5123f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
5124f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
5125f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
5126f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
5127f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
5128f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
5129f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
5130c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
5131f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
5132f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
513351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
513451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
5135f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
5136f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5137189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
51382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
51392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
51402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
5141189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
5142189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5143189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
5144189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5145189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
5146189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5147189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
5148189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5149189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
515014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
515114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
515214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
515314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
515414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
515514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
515614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
515714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
515814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
515953642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
516053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
5161189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
5162189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5163189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5164189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
5165189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
516614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5167189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
5168189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5169189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5170fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
5171fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
5172fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
5173fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
5174fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
5175fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
5176fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
5177fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
517800c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
5179fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
518093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
518176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
518276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
518376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
518476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
518576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
518693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
518793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
518893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
51897260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
51907260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
51917260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
5192aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
519376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
5194aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
5195aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
519693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
519776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
519893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
519993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
520076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
520176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
5202aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
52037260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
52047260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
52057260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
520693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
520793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
520893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
520976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
521076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
521176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
521276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
521376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
521476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
521576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
52165402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
52175402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
52185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
52196dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5220aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
52215402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
52225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5223aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5224aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
52256dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
52266dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
52276dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5228aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
52295402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
52305402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5231aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5232aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
52336dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
52346dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
52351e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
52361e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
52378213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
52381e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
52391e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
52401e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
52411e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5242189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5243189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5244189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5245189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5246189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5247d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
524884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
5249bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
52509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
52517945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
52527945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
52537945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
52547945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
52557945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
52567945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
52577945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_8:  Spacing = 1; return ARM::VST1LNd8;
52587945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
52597945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
52609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
52627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
52637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
52647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
52657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
52667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
52677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
52687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
52697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
52707945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
52717945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
52727945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
52737945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
52747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_8:  Spacing = 1; return ARM::VST2LNd8;
52757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
52767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
52777945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
52787945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
5279d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
52804adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  // VST3LN
52817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
52827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
52837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
52847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
52857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
52867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
52877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
52887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
52897945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
52907945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
52917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_8:  Spacing = 1; return ARM::VST3LNd8;
52927945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
52937945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
52947945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
52957945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
52964adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
5297d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3
52987945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
52997945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
53007945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
53017945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
53027945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
53037945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
53047945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
53057945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
53067945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
53077945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
53087945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
53097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
53107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_8:  Spacing = 1; return ARM::VST3d8;
53117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
53127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
53137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_8:  Spacing = 2; return ARM::VST3q8;
53147945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
53157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
5316539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
531788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  // VST4LN
531888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
531988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
532088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
532188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
532288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
532388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
532488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
532588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
532688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
532788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
532888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:  Spacing = 1; return ARM::VST4LNd8;
532988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
533088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
533188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
533288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
533388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
5334539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4
5335539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5336539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5337539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5338539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5339539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5340539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5341539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5342539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5343539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5344539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5345539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5346539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5347539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:  Spacing = 1; return ARM::VST4d8;
5348539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
5349539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
5350539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:  Spacing = 2; return ARM::VST4q8;
5351539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
5352539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
535384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
535484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
535584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
5356d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
53577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
5358bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
53599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
53607945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
53617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
53627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
53637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
53647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
53657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
53667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_8:  Spacing = 1; return ARM::VLD1LNd8;
53677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
53687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
53699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
53709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
53717945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
53727945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
53737945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
53747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
53757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
53767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
53777945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
53787945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
53797945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
53807945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
53817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_8:  Spacing = 1; return ARM::VLD2LNd8;
53827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
53837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
53847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
53857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
53863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
53875e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP
53885e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
53895e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
53905e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
53915e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
53925e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPq16_UPD;
53935e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
53945e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
53955e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
53965e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
53975e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
53985e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
53995e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
54005e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:  Spacing = 1; return ARM::VLD3DUPd8;
54015e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
54025e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
54035e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
54045e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
54055e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
54065e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
54073a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  // VLD3LN
54087945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
54097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
54107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
54117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
54127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
54137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
54147945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
54157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
54167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
54177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
54187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_8:  Spacing = 1; return ARM::VLD3LNd8;
54197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
54207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
54217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
54227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
5423c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
5424c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3
54257945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
54267945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
54277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
54287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
54297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
54307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
54317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
54327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
54337945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
54347945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
54357945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
54367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
54377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_8:  Spacing = 1; return ARM::VLD3d8;
54387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
54397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
54407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;
54417945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
54427945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
54438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
5444e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  // VLD4LN
5445e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5446e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5447e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5448e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNq16_UPD;
5449e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5450e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5451e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5452e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5453e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
5454e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5455e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:  Spacing = 1; return ARM::VLD4LNd8;
5456e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
5457e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
5458e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
5459e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
5460e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
5461a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP
5462a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5463a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5464a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5465a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
5466a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
5467a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5468a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5469a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5470a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5471a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
5472a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
5473a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5474a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:  Spacing = 1; return ARM::VLD4DUPd8;
5475a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
5476a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
5477a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
5478a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
5479a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
5480a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
54818abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  // VLD4
54828abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
54838abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
54848abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
54858abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
54868abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
54878abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
54888abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
54898abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
54908abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
54918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
54928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
54938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
54948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8;
54958abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
54968abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
54978abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8;
54988abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
54998abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
55007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
55017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
55027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
550383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5504f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5505f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5506f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
55070b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  // Aliases for alternate PC+imm syntax of LDR instructions.
55080b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRpcrel:
55090b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRpci);
55100b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55110b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRBpcrel:
55120b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRBpci);
55130b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55140b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRHpcrel:
55150b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRHpci);
55160b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55170b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSBpcrel:
55180b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSBpci);
55190b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55200b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSHpcrel:
55210b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSHpci);
55220b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
55248b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
55258b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
55268b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32: {
552784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
552884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
552984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
55305b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5531d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
553284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
553384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
553484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
553584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
553684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
553784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
553884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
553984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
554084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
554184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
554284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
55439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55448b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
55458b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
55468b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
55478b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
55488b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32: {
55499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
55509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
55525b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5553d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
55549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55595b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55605b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
55619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
55649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
55659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
55669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
55674adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
55684adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:
55694adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16:
55704adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32:
55714adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16:
55724adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: {
55734adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
55744adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55754adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
55764adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
55774adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
55784adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55794adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55804adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55814adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55824adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55834adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55844adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
55854adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55864adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
55874adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55884adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55894adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
55904adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
55914adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
55924adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
55934adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
559488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:
559588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16:
559688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32:
559788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16:
559888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: {
559988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
560088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
560188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
560288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
560388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
560488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
560588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
560688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
560788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
560888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
560988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
561088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
561188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
561288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
561388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
561488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
561588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
561688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
561788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
561888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
561988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
562088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
562188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
56228b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
56238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
56248b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: {
562584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
562684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
562784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
56285b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5629d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
563084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
563184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
563284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
563384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
563484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
563584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
563684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
563784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
563884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
563984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
564084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
56419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56428b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
56438b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
56448b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
56458b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
56468b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: {
56479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
56489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
56505b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5651d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
56529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56575b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56585b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
56599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
56639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
56649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
56654adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
56664adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:
56674adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16:
56684adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32:
56694adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16:
56704adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: {
56714adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
56724adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56734adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
56744adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
56754adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
56764adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56774adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56784adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56794adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56804adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56814adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56824adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
56834adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56844adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
56854adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56864adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56874adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56884adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
56894adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
56904adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
56914adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
569288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:
569388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16:
569488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32:
569588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16:
569688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: {
569788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
569888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
569988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
570088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
570188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
570288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
570388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
570488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
570588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
570688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
570788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
570888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
570988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
571088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
571188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
571288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
571388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
571488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
571588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
571688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
571788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
571888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
571988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
57208b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
57218b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
57228b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32: {
572384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
572484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
572584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
57265b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5727d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
572884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
572984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
573084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
573184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
573284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
573384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
573484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
573584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
573684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
57379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
57388b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
57398b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
57408b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
57418b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
57428b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32: {
57439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
57449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
57465b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5747d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57515b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57525b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
57539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
57579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
57589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
57594adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
57604adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_8:
57614adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_16:
57624adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_32:
57634adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_16:
57644adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_32: {
57654adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
57664adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57674adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
57684adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
57694adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57704adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57714adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57724adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57734adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57744adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
57754adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57764adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
57774adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57784adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57794adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
578088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
578188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
578288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
578388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
578488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:
578588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16:
578688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32:
578788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16:
578888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: {
578988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
579088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
579188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
579288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
579388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
579488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
579588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
579688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
579788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
579888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
579988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
580088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
580188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
580288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
580388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
580488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
580588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
58064adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
58074adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
58084adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
58094adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
58109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
58118b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
58128b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
58138b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: {
5814872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5815872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5816872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
581795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5818d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5819872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5820872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5821872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5822872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5823872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5824872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5825872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5826872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5827872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5828872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5829872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5830872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
58319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58328b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
58338b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
58348b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
58358b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
58368b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: {
58379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
584095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5841d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
58429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
584395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
584495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
58459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
58499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
585095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
585195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
58529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
58549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
58559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
58569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
58579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
58589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
58603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
58613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
58623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
58633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: {
58643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
58653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
58663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
58673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
5868d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
58693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
58723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5873c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
58743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
58783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
58793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58803a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
58813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5882c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
58833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
58853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
58863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
58873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
58883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
58893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
5890e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:
5891e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16:
5892e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32:
5893e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16:
5894e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: {
5895e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
5896e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
5897e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
5898e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
5899e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5900e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5901e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5902e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5903e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5904e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5905e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5906e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5907e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5908e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5909e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5910e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5911e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5912e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5913e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5914e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5915e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5916e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5917e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5918e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5919e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5920e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5921e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
5922e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
5923e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
5924e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
59258b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
59268b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
59278b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: {
5928872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5929872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5930872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
593195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5932d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5933872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5934872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5935872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5936872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5937872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
5938872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5939872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5940872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
5941872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
5942872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5943872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5944872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
59459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59468b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
59478b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
59488b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
59498b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
59508b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: {
59519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
59529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
595495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5955d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
595795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
59609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
59639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
596495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
596595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
59709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
59719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
59729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
59743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
59753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
59763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
59773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: {
59783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
59793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
59803a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
59813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
5982d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
59863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5987c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
59883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
59893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59903a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59913a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
59923a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
59933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
59953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5996c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
59973a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59983a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59993a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60003a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
60013a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
60023a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
60033a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6004e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:
6005e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16:
6006e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32:
6007e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16:
6008e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: {
6009e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6010e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6011e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6012e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6013e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6014e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6015e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6016e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6017e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6018e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6019e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6020e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6021e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6022e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6023e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6024e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6025e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6026e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6027e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6028e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6029e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6030e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6031e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6032e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6033e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6034e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6035e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6036e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6037e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6038e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
60398b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
60408b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
60418b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32: {
60427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
60437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
60447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
604595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6046d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
60557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
60567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
60579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
60588b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
60598b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
60608b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
60618b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
60628b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32: {
60639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
60649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
60659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
606695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6067d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
606995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
607095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
607495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
607595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
60809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
60819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
60823a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
60833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
60843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
60853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
60863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
60873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32: {
60883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
60893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
60903a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
60913a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6092d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60963a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6097c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60983a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60993a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
61003a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
61013a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61023a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61033a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6104c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61053a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
61063a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61073a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61083a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
61093a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
61103a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
61113a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6112e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:
6113e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16:
6114e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32:
6115e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16:
6116e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: {
6117e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6118e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6119e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6120e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6121e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6122e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6123e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6124e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6125e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6126e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6127e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6128e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6129e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6130e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6131e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6132e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6133e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6134e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6135e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6136e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6137e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6138e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6139e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6140e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6141e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6142e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6143e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6144e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
61455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP single 3-element structure to all lanes instructions.
61465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:
61475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16:
61485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32:
61495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8:
61505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16:
61515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: {
61525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61615e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61625e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
61635e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
61645e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61655e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
61665e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
61675e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
61685e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:
61695e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16:
61705e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32:
61715e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8:
61725e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16:
61735e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: {
61745e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61755e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61765e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61775e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61785e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61795e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61805e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61815e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61825e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61835e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
61845e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61855e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61865e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
61875e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
61885e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61895e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
61905e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
61915e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
61925e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:
61935e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16:
61945e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32:
61955e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8:
61965e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16:
61975e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: {
61985e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61995e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
62005e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62015e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
62025e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62035e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
62045e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62055e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
62065e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
62075e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
62085e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
62095e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
62105e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62115e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62125e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
62135e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
62145e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
62155e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
6216c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3 multiple 3-element structure instructions.
6217c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_8:
6218c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_16:
6219c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_32:
6220c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_8:
6221c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_16:
6222c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_32: {
6223c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6224c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6225d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6226c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6227c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6228c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6229c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6230c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6231c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6232c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6233c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6234c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6235c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6236c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6237c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6238c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6239c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:
6240c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16:
6241c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32:
6242c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:
6243c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16:
6244c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: {
6245c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6246c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6247d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6248c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6249c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6250c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6251c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6252c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6253c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6254c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6255c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6256c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6257c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6258c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6259c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6260c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6261c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6262c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6263c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:
6264c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_16:
6265c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_32:
6266c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:
6267c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_16:
6268c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: {
6269c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6270c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6271d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6272d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6273d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6274d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6275d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6276d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6277d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6278d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6279d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6280d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6281d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6282d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6283d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6284d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6285d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6286d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6287a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP single 3-element structure to all lanes instructions.
6288a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:
6289a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16:
6290a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32:
6291a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8:
6292a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16:
6293a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: {
6294a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6295a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6296a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6297a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6298a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6299a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6300a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6301a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6302a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6303a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6304a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6305a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6306a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6307a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6308a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6309a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6310a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6311a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6312a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:
6313a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16:
6314a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32:
6315a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8:
6316a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16:
6317a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: {
6318a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6319a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6320a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6321a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6322a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6323a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6324a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6325a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6326a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6327a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6328a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6329a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6330a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6331a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6332a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6333a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6334a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6335a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6336a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6337a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6338a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:
6339a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16:
6340a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32:
6341a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8:
6342a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16:
6343a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: {
6344a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6345a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6346a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6347a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6348a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6349a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6350a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6351a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6352a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6353a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6354a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6355a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6356a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6357a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6358a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6359a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6360a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6361a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6362a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6363a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6364a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4 multiple 4-element structure instructions.
63658abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:
63668abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16:
63678abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32:
63688abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:
63698abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16:
63708abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: {
63718abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
63728abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
63738abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63748abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63758abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63768abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
63778abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63788abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
63798abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63808abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
63818abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63828abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63838abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63848abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63858abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
63868abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
63878abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
63888abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
63898abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:
63908abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16:
63918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32:
63928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:
63938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16:
63948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: {
63958abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
63968abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
63978abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63988abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63998abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64008abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
64018abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64028abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
64038abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64048abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
64058abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
64068abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
64078abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
64088abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
64098abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
64108abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
64118abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
64128abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
64138abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
64148abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
64158abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:
64168abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16:
64178abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32:
64188abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:
64198abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16:
64208abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: {
64218abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
64228abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
64238abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
64248abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
64258abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64268abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
64278abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64288abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
64298abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64308abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
64318abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
64328abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
64338abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
64348abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
64358abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
64368abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
64378abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
64388abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
64398abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
64408abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
6441d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3 multiple 3-element structure instructions.
6442d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_8:
6443d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_16:
6444d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_32:
6445d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_8:
6446d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_16:
6447d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_32: {
6448d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6449d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6450d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6451d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6452d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6453d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6454d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6455d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6456d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6457d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6458d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6459d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6460d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6461d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6462d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6463d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6464d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:
6465d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16:
6466d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32:
6467d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:
6468d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16:
6469d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: {
6470d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6471d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6472d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6473d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6474d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6475d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6476d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6477c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6478c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6479c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6480c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6481c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6482d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6483d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6484d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6485d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6486d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6487d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6488d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_8:
6489d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_16:
6490d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_32:
6491d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_8:
6492d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_16:
6493d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_32: {
6494d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6495d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6496d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6497c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6498c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6499c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6500c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6501d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6502d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6503d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6504d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6505d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6506c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6507c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6508c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6509c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6510c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6511c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6512539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4 multiple 3-element structure instructions.
6513539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:
6514539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16:
6515539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32:
6516539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:
6517539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16:
6518539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: {
6519539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6520539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6521539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6522539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6523539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6524539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6525539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6526539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6527539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6528539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6529539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6530539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6531539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6532539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6533539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6534539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6535539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6536539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6537539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:
6538539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16:
6539539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32:
6540539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:
6541539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16:
6542539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: {
6543539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6544539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6545539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6546539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6547539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6548539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6549539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6550539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6551539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6552539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6553539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6554539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6555539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6556539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6557539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6558539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6559539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6560539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6561539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6562539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6563539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:
6564539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16:
6565539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32:
6566539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:
6567539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16:
6568539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: {
6569539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6570539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6571539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6572539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6573539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6574539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6575539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6576539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6577539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6578539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6579539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6580539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6581539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6582539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6583539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6584539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6585539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6586539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6587539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6588539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6589863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
65902cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVsr:
65912cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVSsr: {
65922cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
65932cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // whether we're in an IT block if the register operands are low
65942cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // registers.
65952cc5cda464e7c936215281934193658cb799c603Jim Grosbach    bool isNarrow = false;
65962cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
65972cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
65982cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(2).getReg()) &&
65992cc5cda464e7c936215281934193658cb799c603Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
66002cc5cda464e7c936215281934193658cb799c603Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
66012cc5cda464e7c936215281934193658cb799c603Jim Grosbach      isNarrow = true;
66022cc5cda464e7c936215281934193658cb799c603Jim Grosbach    MCInst TmpInst;
66032cc5cda464e7c936215281934193658cb799c603Jim Grosbach    unsigned newOpc;
66042cc5cda464e7c936215281934193658cb799c603Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
66052cc5cda464e7c936215281934193658cb799c603Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
66062cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
66072cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
66082cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
66092cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
66102cc5cda464e7c936215281934193658cb799c603Jim Grosbach    }
66112cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.setOpcode(newOpc);
66122cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
66132cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isNarrow)
66142cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
66152cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
66162cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
66172cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
66182cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
66192cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
66202cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (!isNarrow)
66212cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
66222cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
66232cc5cda464e7c936215281934193658cb799c603Jim Grosbach    Inst = TmpInst;
66242cc5cda464e7c936215281934193658cb799c603Jim Grosbach    return true;
66252cc5cda464e7c936215281934193658cb799c603Jim Grosbach  }
6626863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
6627863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
6628863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
6629863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
6630863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
6631863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
6632863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6633863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6634863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
6635863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
6636863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
6637863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
6638863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
6639863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6640863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
6641863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
6642863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
6643863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
6644520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
6645863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
6646863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
6647863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (Ammount == 32) Ammount = 0;
6648863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
6649863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
6650863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
6651863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6652863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6653863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6654520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    if (newOpc != ARM::t2RRX)
6655520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Ammount));
6656863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6657863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6658863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
6659863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6660863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6661863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
6662863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
6663863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
6664863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
666523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
666623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
666723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
666823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
666923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
667023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
667123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
667223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
667323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
667423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
667523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
667623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
667723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
667823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
667923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
668023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
668123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
668223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
668323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
668423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
668523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
668623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
668723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
668823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
668923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
6690ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
6691ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
6692ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
6693ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
6694ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
6695ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
6696ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6697ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
6698ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
6699ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
6700ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
6701ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
6702ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
670348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
6704ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
6705ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
670671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
6707ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
670871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
670971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6710ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
6711ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
671271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
671371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
671471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
671571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
671683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
671771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
671848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
671948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
672048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
672148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
672248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
672348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
672448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
672548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
672648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
672748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
672848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
672948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
673048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
67310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
67320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
67330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
67340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
67350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
67360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
67370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
67380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
67390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
67400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
67410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
67420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
67430352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
67440352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
67450352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
67460352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
67470352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
67480352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
67490352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
67500352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
67510352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
67520352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
67530352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
67540352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
67550352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
67560352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
67570352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
67580352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
67590352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
67600352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
67610352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
67620352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
6763f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
6764f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
6765f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
6766f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
6767f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
6768f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
6769f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
6770f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6771f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6772f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
6773f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
6774f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
6775f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6776f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6777f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
677883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6779f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
6780f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
6781f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
6782f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
6783f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
6784f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
6785f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
6786f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
6787f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
6788f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6789f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6790f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
6791f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
6792f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6793f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6794f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
6795f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
6796f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
6797da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
6798da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
6799da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
6800da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
6801da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6802da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6803da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
6804da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6805da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
6806da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
6807da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
6808da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
6809da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
6810da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6811da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6812da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
6813da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6814da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
681589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
68160f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
68170f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
68180f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
68190f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
682083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
682189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
682283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
682383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
682489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
6825f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
6826f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
6827f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
6828f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
6829f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
683083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
6831f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
683283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
683383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6834f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
6835927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
6836927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
6837927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
6838927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
6839927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
6840927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
6841927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
6842713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
6843713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
6844927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
6845927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
6846927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
6847927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6848927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6849927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
6850927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
6851927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6852927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
6853927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
6854927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
685551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
685651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
685783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
685851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
685983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
686083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
686151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
686251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
686351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
686483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
686551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
686683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
686783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
686851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
6869c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
6870a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
687183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
6872c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
687383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
687483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6875c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
6876395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
6877395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
687883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
6879395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
688083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
688183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
68823ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
688376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
688476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
688576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
688676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
688776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
688876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
688976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
689076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
689176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
689276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
689376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
689476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
689576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
689676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
689776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
689876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
689976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
690076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
690176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
690276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
690376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
690483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
690576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
690676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
690776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
69088213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
69098213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
69108213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
69118213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
69128213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
69138213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
69148213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
69158213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
69168213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
69178213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
691883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69198213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
69208213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
69218213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
69225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
69235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
69245402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
69255402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
69265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
69275402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
692883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
69295402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
69305402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
69315402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
69325402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
69335402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
693483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
69355402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
69365402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
69375402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
69385402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
693983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
69405402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
69415402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
69425402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
69435402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
69445402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
694583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
69465402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
69471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
69481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
69491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
69501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
69511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
6952c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
6953c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
6954c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
69551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
69561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
69571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
69581ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
69591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
69601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
69611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
69621ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
69631ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
69641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
69651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
696683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69671ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
69681ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
69691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
69701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
69711ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
69721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
69731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
69741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
69751ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
69761ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
69771ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
69781ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
69791ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
69801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
69811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
69821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
69831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
69841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
69851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
69861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
698783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
69891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
69901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
6991326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
699250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
699350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
699450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
6995326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
6996326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
6997326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6998326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6999326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
7000326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
7001326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
700250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
700350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
700450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
700550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
700650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
700750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
700850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
700950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
7010326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
7011326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
7012326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
7013326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
7014326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
7015326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
7016326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
7017326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
701883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
7019326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
7020326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
7021326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
702204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  case ARM::MOVsi: {
702304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
702404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (SOpc == ARM_AM::rrx) return false;
702504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
702604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      // Shifting by zero is accepted as a vanilla 'MOVr'
702704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      MCInst TmpInst;
702804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
702904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
703004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
703104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
703204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
703304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
703404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      Inst = TmpInst;
703504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      return true;
703604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    }
703704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    return false;
703804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  }
70398d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ANDrsi:
70408d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ORRrsi:
70418d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::EORrsi:
70428d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::BICrsi:
70438d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::SUBrsi:
70448d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ADDrsi: {
70458d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    unsigned newOpc;
70468d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
70478d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (SOpc == ARM_AM::rrx) return false;
70488d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    switch (Inst.getOpcode()) {
7049bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("unexpected opcode!");
70508d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
70518d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
70528d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::EORrsi: newOpc = ARM::EORrr; break;
70538d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::BICrsi: newOpc = ARM::BICrr; break;
70548d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
70558d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
70568d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
70578d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    // If the shift is by zero, use the non-shifted instruction definition.
70588d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) {
70598d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      MCInst TmpInst;
70608d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.setOpcode(newOpc);
70618d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
70628d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
70638d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
70648d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
70658d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
70668d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(6));
70678d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      Inst = TmpInst;
70688d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      return true;
70698d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
70708d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    return false;
70718d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  }
707274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  case ARM::ITasm:
707389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
707489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
707589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
707689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
707789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
707889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
707989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
708089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
708189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
7082f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
7083f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
708489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
708589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
708689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
708789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
708889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
708989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
709089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
7091f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
7092f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
7093f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
7094f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
7095f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
7096f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
7097f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
7098f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
709989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
710089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
7101f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
710283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
7103f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
7104f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
710547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
710647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
710747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
7108194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
71091a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
711047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
711147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
711247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
711347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
711447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
711547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
711647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
711747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
711847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
711947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
712047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
712147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
712247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
712347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
712447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
712547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
7126f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
7127f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
712847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
7129f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
7130f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
7131f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
713247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
7133194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
7134194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
7135194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
7136194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
7137194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
7138194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
7139194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
71404ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
7141194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
7142194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
7143194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
714447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
714547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
714647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
7147fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
7148fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
7149fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7150fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
7151fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
7152fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
715319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
7154193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
7155193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
715619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
7157e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
7158189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
7159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
7160a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
7161a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
7162a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
7163a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
7164189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
7165a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
7166189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
7167f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
716883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
716983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
717083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
717183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
717283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
7173f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
7174a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
7175a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
7176a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
7177a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
7178a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
717974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
718074423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // doesn't actually encode.
718174423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    if (Inst.getOpcode() == ARM::ITasm)
718274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      return false;
718374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach
718442e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Inst.setLoc(IDLoc);
7185fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
7186fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
7187e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
7188e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
7189e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
7190e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
7191e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
7192e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
7193e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
7194e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
719516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7196e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
7197e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
7198e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
719916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7200e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
7201e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
7202e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
720347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
7204b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
720588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
720688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
7207f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
7208f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
720947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
721047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
7211194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
7212194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
7213194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
7214194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
7215fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
721616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7217c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
7218fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
7219fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
72201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
7221ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
7222ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
7223ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
72241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
7225515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
72261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
72279a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
72289a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
7229515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
72301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
7231515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
72321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
7233515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
72341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
7235a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
7236a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
7237d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".arch")
7238d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveArch(DirectiveID.getLoc());
7239d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".eabi_attribute")
7240d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveEabiAttr(DirectiveID.getLoc());
7241ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
7242ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7243ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
72441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
7245ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
72461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
7247ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
7248ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
7249ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
7250ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
7251ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
7252ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7253aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
7254ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7255ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
7256ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
725716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7258ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
7259ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
7260ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
7261b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
7262ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
7263ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
7264ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7265b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7266ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
7267ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7268ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
72691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
7270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
72711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
7272515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
7273515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7274b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7275515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
72769a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
72779a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
72789a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
72799a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
72809a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
72819a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
72829a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
72839a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
72849a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
72859a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
72869a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
72879a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
72889a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
72899a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
72909a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
72919a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7292515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7293515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7294515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
72951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
7296515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
72971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
72986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
72996469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
73006469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
7301de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  bool needFuncName = true;
73026469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7303de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Darwin asm has (optionally) function name after .thumb_func direction
73046469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
73056469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
73066469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
7307de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    if (Tok.isNot(AsmToken::EndOfStatement)) {
7308de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
7309de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach        return Error(L, "unexpected token in .thumb_func directive");
7310de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Name = Tok.getIdentifier();
7311de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Parser.Lex(); // Consume the identifier token.
7312de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      needFuncName = false;
7313de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    }
73146469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
73156469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7316de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
7317515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7318de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach
7319de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Eat the end of statement and any blank lines that follow.
7320de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  while (getLexer().is(AsmToken::EndOfStatement))
7321de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    Parser.Lex();
7322515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
7324de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // We really should be checking the next symbol definition even if there's
7325de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // stuff in between.
7326de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (needFuncName) {
7327d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
73286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
73296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7330642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
7331642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
7332642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
7333515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7334515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7335515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
7337515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
73381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
733918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7340515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
7341515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
734238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
734358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
7344b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
734558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
73469e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
7347515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7348515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
7349515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7350515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
735118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7352b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7353515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7354515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
7355515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
7356515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7357515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7358515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
7360515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
73611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
736218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7363515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
7364515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
736518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
736658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
7367b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
736858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
7369b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
7370515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7371515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
7372515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7373515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
737418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7375b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7376515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
737732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
737898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
7379ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
738098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
738132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
738298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
7383ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
738498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7385eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
73862a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
7387515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7388515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7389515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7390a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
7391a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
7392a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7393a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
7394a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
7395a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
7396a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
7397a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7398a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
7399a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7400a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7401a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
7402a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7403a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7404a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
7405a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
7406a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7407a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7408a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
7409a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7410a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
7411a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
7412a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
7413a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7414a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7415a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7416a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7417a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
7418a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
7419a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
7420a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
7421a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7422a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
7423a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7424a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
7425a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
7426a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7427a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7428a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7429d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch
7430d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .arch token
7431d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) {
7432d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7433d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7434d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
7435d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr
7436d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .eabi_attribute int, int
7437d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
7438d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7439d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7440d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
744190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
744290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
74439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
7444ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
744594b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
744694b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
744790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
7448ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
74493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
74500692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
74510692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
74523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
7453