ARMAsmParser.cpp revision 359956dc1be35df4f8179eb14cea617c3ef10dd7
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h"
2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h"
3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbachenum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
4398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
4494b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
4728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  const MCRegisterInfo *MRI;
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
49a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Map of register aliases registers via the .req directive.
50a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StringMap<unsigned> RegisterReqs;
51a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
68f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
69f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
70f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
71f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
76a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
77a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
78a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
79a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
80f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
81f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
84ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
85362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  bool Warning(SMLoc L, const Twine &Msg,
86362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer               ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
87362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer    return Parser.Warning(L, Msg, Ranges);
88362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  }
89362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  bool Error(SMLoc L, const Twine &Msg,
90362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer             ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
91362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer    return Parser.Error(L, Msg, Ranges);
92362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  }
93ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
960d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
1017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
1027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
1031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
1041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
1059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
1061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
1071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
109a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveReq(StringRef Name, SMLoc L);
110a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveUnreq(SMLoc L);
111d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveArch(SMLoc L);
112d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveEabiAttr(SMLoc L);
113515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
11589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
11689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
118fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
120ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
121ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
122ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
123ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
124ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
125ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
126ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
12747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
12847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
130194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
131194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
132194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
133acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
134acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
135acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
13632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
137ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
138ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
140acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
141acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
142acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
143ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1470692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1480692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
149a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
15343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
154f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
156f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1608bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
16143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1628bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
16343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1648bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
166f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
167f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
168f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
169f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
170f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
171f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
172f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
173c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
174580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
176293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
178251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1799d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
180862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
182ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
183ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
184359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
185a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
186359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
187a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
188359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
189eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
190359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
191ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
192359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
193ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
194359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
196359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
197548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
198359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
199ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
200359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
2017b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
202359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
204359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
206359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
208359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
210359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdrdPre(MCInst &Inst, unsigned Opcode,
2112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
212359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtStrdPre(MCInst &Inst, unsigned Opcode,
21314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
214359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
215623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
216359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
21788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
218359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
21912431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
220359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
22112431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
222359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2234334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
224359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosier  void cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2254334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
226189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
227189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
228189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
230f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
231d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
232d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
233189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
234ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
23547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
236194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
237f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
238194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
23970c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    Match_RequiresThumb2,
24070c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach#define GET_OPERAND_DIAGNOSTIC_TYPES
24170c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach#include "ARMGenAsmMatcher.inc"
24270c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach
24347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
24447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
245ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
24694b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
247ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
24832869205052430f45d598fba25ab878d8b29da2dEvan Cheng
24928f08c93e75d291695ea89b9004145103292e85bJim Grosbach    // Cache the MCRegisterInfo.
25028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    MRI = &getContext().getRegisterInfo();
25128f08c93e75d291695ea89b9004145103292e85bJim Grosbach
252ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
253ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
254f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
256f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
257ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
258ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
262189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
26547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
26647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
270ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
27116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
27216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2733a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2743a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
275a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
276a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
277146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
28621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
28721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
28821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
28921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
291460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
29221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
29321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
29421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
29521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
296862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
29798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
29921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
30021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
30121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
30221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
30321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
30421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
30824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
311a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
3128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
3138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
316fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
317fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
32489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
32589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
32689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
32789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
32889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
32989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
33089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
33189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
335a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
340a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
341a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
342a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
344a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
345a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
346a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
347a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
348862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
349862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
350862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
351862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3530aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
354862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
355862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3568155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
357460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
358460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
359460a90540b045c102012da2492999557e6840526Jim Grosbach
360460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
361cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
362cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
36316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3646a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
365a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
366a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
37257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
37357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
374eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
376e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
380f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
381f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
382f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
386580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
387e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
388580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
389e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
390e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
391e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
392e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
393e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
394af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
39592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
39692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
39792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
39892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
399af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
4007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
4017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
4027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
403293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
404293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
405293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
406293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
407a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
40816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
409146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
410146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
412762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
413762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
414762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
41621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4178462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4188462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
41921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
42089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
42189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
42221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
424762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
427762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
428762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
43121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
43224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4338d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
434862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
43598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4367636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
437862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
438862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
44021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
441fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
442fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
44621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
447762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
448762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
450706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
451706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
45221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
453e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
454762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
45521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
45821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
459584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
460584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
46121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
462a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
46421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
46721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
468af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
469e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
47021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
471af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
47292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
47321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
47621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
477293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
478293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
479460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
480460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
481460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
482762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
483762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
48416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
485762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
486762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
487762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
488762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
490362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
491362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer
4928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
497fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
499fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
500fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
501fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
502a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
504a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
50821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
5097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
510a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
511a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5125fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
51321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
51421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
51524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5168d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
518cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
51921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    assert(isImm() && "Invalid access!");
520cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
521cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
522cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
523460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
524460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
525460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
526460a90540b045c102012da2492999557e6840526Jim Grosbach  }
527460a90540b045c102012da2492999557e6840526Jim Grosbach
528706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
530706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
531706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
532706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
538584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
540584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
54421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
54621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
54721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
54821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
54921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
55021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
55151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  bool isFPImm() const {
55251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!isImm()) return false;
55351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
55451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!CE) return false;
55551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
55651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    return Val != -1;
55751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  }
5584050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits16() const {
5594050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5604050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5614050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5624050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5634050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 0 && Value <= 16;
5644050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
5654050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits32() const {
5664050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5674050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5684050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5694050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5704050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 1 && Value <= 32;
5714050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
572a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
57321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
574a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
575a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
576a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
577a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
578a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
57972f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
58021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
58172f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
58272f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
58372f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
58472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
58572f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
58672f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
58721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
58872f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
58972f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
59072f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
59172f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
59272f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5934e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  bool isImm0_508s4Neg() const {
5944e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!isImm()) return false;
5954e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5964e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!CE) return false;
5974e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    int64_t Value = -CE->getValue();
5984e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // explicitly exclude zero. we want that to use the normal 0_508 version.
5994e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    return ((Value & 3) == 0) && Value > 0 && Value <= 508;
6004e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
6016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
60221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
6056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
6066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
6076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6084e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  bool isImm0_4095() const {
6094e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!isImm()) return false;
6104e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6114e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!CE) return false;
6124e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    int64_t Value = CE->getValue();
6134e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    return Value >= 0 && Value < 4096;
6144e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
6154e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  bool isImm0_4095Neg() const {
6164e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!isImm()) return false;
6174e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6184e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    if (!CE) return false;
6194e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    int64_t Value = -CE->getValue();
6204e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    return Value > 0 && Value < 4096;
6214e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
622587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
62321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
624587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
625587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
626587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
627587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
628587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
629587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
63021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
631587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
632587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
633587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
634587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
635587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
63683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
63721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
63883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
63983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
64083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
64183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
64283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
64383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
64421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
64583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
64683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
64783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
64883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
64983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6507c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
65121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6527c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6537c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6547c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6567c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
657730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
65821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
659730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
660730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
661730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
662730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
663730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6643b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
66521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6663b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6673b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6683b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6693b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6703b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6713b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
67221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6733b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6743b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6753b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6763b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6773b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
67921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6813b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6856b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
68621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6876b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6886b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6896b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6906b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6916b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6926b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
69321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6946b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6956b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6966b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6976b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6986b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6996b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
70021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7016b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7026b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
7036b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
7046b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
7056b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
7066b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
70721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7086b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7096b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
7106b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
7116b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
7126b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
7133b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
71421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7153b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7163b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7173b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7183b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
7193b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
7203b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
72121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7223b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7233b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7243b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7253b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
7263b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
7273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
72821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
7333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
734f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
73521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
736f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
737f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
738f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
739f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
740f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7414a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
74221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7434a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7444a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7454a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7464a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7474a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
748ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
74921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
750ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
751ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
752ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
753ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
754ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
755fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
75621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
757fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
758fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
759fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
760fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
761fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
762ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
76321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
764ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
765ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
766ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
767ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
768ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
769ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
770ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
771ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
77221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
773ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
774ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
775ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
776ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
777ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
77870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
77921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
78070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
78170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
78270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
78370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
78470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
785f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
78621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
787f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
788f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
789f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
790f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
791f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
792f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
79321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
794f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
795f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
796f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
797f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
798f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7991fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  bool isAdrLabel() const {
8001fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // If we have an immediate that's not a constant, treat it as a label
8011fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // reference needing a fixup. If it is a constant, but it can't fit
8021fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // into shift immediate encoding, we reject it.
8031fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    if (isImm() && !isa<MCConstantExpr>(getImm())) return true;
8041fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    else return (isARMSOImm() || isARMSOImmNeg());
8051fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  }
8066bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
80721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8086bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8096bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
8106bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
8116bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
8126bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
813e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
81421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
815e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
816e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
817e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
818e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
819e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
8203bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
82121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8223bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8233bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8243bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
825ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    // Only use this when not representable as a plain so_imm.
826ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    return ARM_AM::getSOImmVal(Value) == -1 &&
827ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach      ARM_AM::getSOImmVal(-Value) != -1;
8283bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
8296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
83021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
8336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
8346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
8356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
83689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
83721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
83889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
83989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
84089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
84189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
84289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
8433bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
84421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8453bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8463bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8473bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
848ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    // Only use this when not representable as a plain so_imm.
849ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach    return ARM_AM::getT2SOImmVal(Value) == -1 &&
850ad353c630359d285018a250d72c80b7022d8e67eJim Grosbach      ARM_AM::getT2SOImmVal(-Value) != -1;
8513bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
852c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
85321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
854c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
855c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
856c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
857c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
858c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
85921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
86021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
86121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
86221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
86321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
86421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
86521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
86621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
86721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
86821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
86921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
87021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
87121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
872f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
873430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
874f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
87557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
876f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
877ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
87957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
88057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
88157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
8820b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  bool isMemPCRelImm12() const {
8830b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
8840b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8850b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base register must be PC.
8860b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum != ARM::PC)
8870b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8880b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Immediate offset in range [-4095, 4095].
8890b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!Memory.OffsetImm) return true;
8900b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8910b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8920b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
89357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
89457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
895ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
89757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
899e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
9007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
901e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
902e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
9047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
905039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
90621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
907039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
908039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
909039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
910039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
911039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
912039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
9132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
9142f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
9152f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
9162f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
91721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
9182f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
91957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
921e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
9222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
923e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
9242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
925e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
926e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
927ca3cd419a52c1dedee133d79772ef97f30e5d20bSilviu Baranga    // The #-0 offset is encoded as INT32_MIN, and we have to check
928ca3cd419a52c1dedee133d79772ef97f30e5d20bSilviu Baranga    // for this too.
929ca3cd419a52c1dedee133d79772ef97f30e5d20bSilviu Baranga    return (Val > -256 && Val < 256) || Val == INT32_MIN;
9302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
9312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
93221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
9332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
93421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
9352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
9362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
9372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
9392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
940251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
941251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
9422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
944681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
945681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
946681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
94721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
948681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
94957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
951e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
953e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
954e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9550da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
956681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9587f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
959e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
96057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9617f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9627f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9637f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9647f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
965e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
96657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
96757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9687f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9697f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9707f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
97257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
973ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
974ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
975ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
976ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
97757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
97857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
979ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
980ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
981e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
982ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
983e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
984ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
985ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
986ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
990e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
99157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
99287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
993e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
994e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
99560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
99660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
997e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
99857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
99960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
100060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
1001e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1002e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1003ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
1004ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
100538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
1006e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
100757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
100838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
100938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
1010e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1011e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
101238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
101338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
101448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
1015e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
101657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
101748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
101848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
1019e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1020e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
102148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
102248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
1023ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
102457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
102557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
1026ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
1027ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
1028e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1029e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1030ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
1031505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1032a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
10332f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
10342f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
10352f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
103621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
10372f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
103857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1039a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
1040a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
1041e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1042e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1043fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    // Special case, #-0 is INT32_MIN.
1044fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    return (Val >= -1020 && Val <= 1020 && (Val & 3) == 0) || Val == INT32_MIN;
1045a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1046b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
104757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1048b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
1049b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
1050e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1051e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1052b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1053b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
105557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1056f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10570b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10580b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
10597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1060e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1061e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10624d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1063f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1064f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
106557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1066f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1067f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1068e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1069e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1070f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1071f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1072a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
107357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1074a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
10750b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10760b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
1077a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1078df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1079e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1080df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1081a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1082a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
108357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1084a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1085a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1086e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1087e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1088a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1089a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
109109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
109209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
109309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
109421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
109509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
109609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
109757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1098ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1100e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1101e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
11020da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
11037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
11047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
110521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
11067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1107ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
11087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
110963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1110ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
11112bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
111221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
11132bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11142bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
11152bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
11162bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
11172bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
11182bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
11197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
112021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
112121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
11223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
11240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
11250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
11260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
11270aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
11280aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
11290aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1130862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
11310aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1133862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1134862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
113528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  bool isVecListDPair() const {
113628f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!isSingleSpacedVectorList()) return false;
113728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
113828f08c93e75d291695ea89b9004145103292e85bJim Grosbach              .contains(VectorList.RegNum));
113928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
114028f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1141cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
11420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1143cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1144cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1145cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1146b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
11470aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1148b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1149b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1150b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
1151c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  bool isVecListDPairSpaced() const {
11529f2e160f7ae90a7a80b17e38ad06f2c706515115Kevin Enderby    if (isSingleSpacedVectorList()) return false;
1153c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1154c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach              .contains(VectorList.RegNum));
1155c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  }
1156c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1157c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  bool isVecListThreeQ() const {
1158c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
1159c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return VectorList.Count == 3;
1160c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
1161c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
11627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  bool isVecListFourQ() const {
11637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    return VectorList.Count == 4;
11657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  }
11667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
11673471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isSingleSpacedVectorAllLanes() const {
11683471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
11693471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11703471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isDoubleSpacedVectorAllLanes() const {
11713471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
11723471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
117398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
11743471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
117598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
117698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
117798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
1178c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  bool isVecListDPairAllLanes() const {
11793471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1180c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1181c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach              .contains(VectorList.RegNum));
11823471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11833471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach
11844d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  bool isVecListDPairSpacedAllLanes() const {
11853471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
118613af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
118713af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
118813af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11895e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeDAllLanes() const {
11905e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11915e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11925e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11935e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
11945e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeQAllLanes() const {
11955e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
11965e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11975e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11985e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
1199a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourDAllLanes() const {
1200a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1201a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1202a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1203a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
1204a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourQAllLanes() const {
1205a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
1206a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1207a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1208a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
120995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isSingleSpacedVectorIndexed() const {
121095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
121195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
121295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isDoubleSpacedVectorIndexed() const {
121395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
121495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
12157636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
121695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12177636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
12187636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
12197636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1220799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
122195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1222799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1223799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1224799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1225799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
122695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1227799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1228799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1229799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
123195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
12339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
12349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1235799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
123695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
123795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
123895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
123995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
124095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQWordIndexed() const {
124195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
124295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
124395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
124495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
124595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQHWordIndexed() const {
124695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1247799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1248799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1249799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1250799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
125195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1252799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1253799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1254799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDByteIndexed() const {
12563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
12583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDHWordIndexed() const {
12613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQWordIndexed() const {
12663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12683a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQHWordIndexed() const {
12713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDWordIndexed() const {
12763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
1280e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDByteIndexed() const {
1281e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1282e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1283e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1284e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1285e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDHWordIndexed() const {
1286e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1287e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1288e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1289e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1290e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQWordIndexed() const {
1291e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1292e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1293e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1294e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1295e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQHWordIndexed() const {
1296e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1297e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1298e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1299e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1300e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDWordIndexed() const {
1301e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1302e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1303e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1304e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1305460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1306460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1307460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1308460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1309460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1310460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1311460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1312460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1313460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1314460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1315460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1316460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1317460a90540b045c102012da2492999557e6840526Jim Grosbach
13180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
131921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
13220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
13230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
13240e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
13250e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
13260e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
13270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1328460a90540b045c102012da2492999557e6840526Jim Grosbach
1329ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
133021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1331ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1332ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1333ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1334ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1335ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1336ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1337ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1338ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
13396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
134021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
13466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
13506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
13526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
135321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13679b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  bool isNEONi32vmovNeg() const {
136821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13699b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13709b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // Must be a constant.
13719b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (!CE) return false;
13729b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    int64_t Value = ~CE->getValue();
13739b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13749b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13759b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    return (Value >= 0 && Value < 256) ||
13769b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13779b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13789b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13799b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13809b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13819b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
13826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1383f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
138421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1385f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1386f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1387f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1388f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1389f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1390f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1391f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1392f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1393f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1394f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
13953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
139614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
139714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
139814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
139914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
14003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
14013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
14023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
14033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
14043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1406345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
14078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
140804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
140904f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
14108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
14118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1412fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1413fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1414fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1415fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1416fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
14179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
14189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
14209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
14219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
14229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
14239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
14259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
14269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
142789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
142889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
142989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
143089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
143189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
143289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
143389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
143489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
143589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
143689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1437d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1438d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1439d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1440d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1441d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1442a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1444a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1446a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1447af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1448e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1449430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1450430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1451af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1452af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1453e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1454af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1455e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1457af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1458152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1459430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1460430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1461af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
1462b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    // Shift of #32 is encoded as 0 where permitted
1463b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
146492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1465b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
146692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
146792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1468580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
14690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1470580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1471580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
14720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
147487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
14757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
14765fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
14775fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
14787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
14797729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
148087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
148187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
14820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
14830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
14870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14890f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
14917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
14937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
14947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1496293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1497293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1498293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1499293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1500293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1501293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1502293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1503293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1504293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1505293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1506293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
15073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
15086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
15106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
15116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
15124050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits16Operands(MCInst &Inst, unsigned N) const {
15134050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15144050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15154050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
15164050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
15174050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
15184050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits32Operands(MCInst &Inst, unsigned N) const {
15194050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15204050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15214050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
15224050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
15234050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
15249d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
15259d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
152651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
152751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
152851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15299d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
15309d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1531a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1532a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1533a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1534a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1535a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1536a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1537a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1538a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
153972f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
154072f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
154172f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
154272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
154372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
154472f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
154572f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
154672f39f8436848885176943b0ba985a7171145423Jim Grosbach
15474e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  void addImm0_508s4NegOperands(MCInst &Inst, unsigned N) const {
15484e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15494e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // The immediate is scaled by four in the encoding and is stored
15504e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // in the MCInst as such. Lop off the low two bits here.
15514e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15524e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-(CE->getValue() / 4)));
15534e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
15544e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach
155572f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
155672f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
155772f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
155872f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
155972f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
156072f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
156172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
156272f39f8436848885176943b0ba985a7171145423Jim Grosbach
1563f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1564f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1565f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1566f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1567f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1568f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1569f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1570f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
15714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
15724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
15744a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
15754a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15764a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
15774a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
15784a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
157970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
158070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
158170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
158270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
158370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
158470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
158570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1586ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1587ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1588f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1589f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1590f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1591f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1592f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1593f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1594f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1595f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1596f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
159789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
159889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
159989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
160089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
160189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
160289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
160389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
160489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
16053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
16063bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16073bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
16083bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
16093bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16103bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
16113bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
16123bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
16134e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  void addImm0_4095NegOperands(MCInst &Inst, unsigned N) const {
16144e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16154e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // The operand is actually an imm0_4095, but we have its
16164e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    // negation in the assembly source, so twiddle it here.
16174e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16184e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
16194e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach  }
16204e53fe8dc61ad48650ac6fe30d7268ec92b7fc1aJim Grosbach
1621e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1622e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1623e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1624e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1625e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1626e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1627e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1628e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
16293bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
16303bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16313bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
16323bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
16333bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16343bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
16353bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
16363bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1637706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1638706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1639706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1640706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1641706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
16427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
16437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1644e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1645505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1646505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
16470b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
16480b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16490b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int32_t Imm = Memory.OffsetImm->getValue();
16500b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // FIXME: Handle #-0
16510b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
16520b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
16530b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
16540b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach
16551fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
16561fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    assert(N == 1 && "Invalid number of operands!");
16571fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    assert(isImm() && "Not an immediate!");
16581fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
16591fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // If we have an immediate that's not a constant, treat it as a label
16601fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    // reference needing a fixup.
16611fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    if (!isa<MCConstantExpr>(getImm())) {
16621fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu      Inst.addOperand(MCOperand::CreateExpr(getImm()));
16631fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu      return;
16641fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    }
16651fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
16661fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16671fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    int Val = CE->getValue();
16681fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu    Inst.addOperand(MCOperand::CreateImm(Val));
16691fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu  }
16701fb27eccf5b7eabde9678d84411eb1df8a693683Jiangning Liu
167157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
167257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
167357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
167457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
167557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
167657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
16777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
16787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1679e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1680e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
16837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
16857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
16867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
16877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
16887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1689e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1690e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1691ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1692e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1693e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1695ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1696ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1697039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1698039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1699039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1700039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1701039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1702039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1703039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1704039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1705039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1706039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1707039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1708039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1709039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1710039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
17112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
17122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
17132f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
17142f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
17152f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
17162f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
17172f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
17182f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
17192f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
17202f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17212f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17222f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1724e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
17252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
17262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
17272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
17282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
17292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
17302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
17312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
17322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1733e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
17342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1735e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1736e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
17392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
17402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
17412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
174221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
17432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
17442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
17452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
17462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1747251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
17482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
17492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
17502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
17512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
17522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
17532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
17542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
17552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
17562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1757251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
17582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
17592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
17612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
17627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
17637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1764681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1765681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1766681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1767681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1768681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1769681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1770681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1771681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1772681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
17737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1774e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
17757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
17767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
17777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
17787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
17797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1780e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
17837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1784a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1785a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
17862f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
17872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
17882f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
17892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
17902f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
17912f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
17922f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17932f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17942f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1795e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1796e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1797a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1798a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1799a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1800b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1801b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1802b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1803e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1804e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1805b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1806b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1807b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
18087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
18097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1811e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
18127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1813ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1814ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1815f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1816f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1817f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1818f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1819a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1820f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1821a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1822a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1823a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1824a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1825a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
182621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
1827a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1828a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1829a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1830a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1831a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1832a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1833e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1834e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1835a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1836a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1837a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
18387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
18397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
184009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
184121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
184209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
184309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
184409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
184509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
184609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
184709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1848e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1849e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
18507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
18517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
185292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
18537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
18547f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1855e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1856e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
18577f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
18587f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
18597f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
18607f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1861e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1862e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
18637f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
18647f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
18657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
18667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1867430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1868430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1869430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1870e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1871e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
18727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
18737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1874d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1875ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1876ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1877e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1878e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1880ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1881ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
18827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
18837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1884e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1885e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
188614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
18873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
188860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
188960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1890e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1891e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
189260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
189348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
189448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
189538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
189638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1897e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1898e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
189938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
190038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
190138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
190248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
190348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1904e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1905e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
190648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
190760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
190860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1909ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1910ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1911e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1912e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1913ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1914ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1915ecd858968384be029574d845eb098d357049e02eJim Grosbach
19167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
19177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
19207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
19217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
192263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
19237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
19247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1925f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1926ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
19272bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
19282bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
19292bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19302bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
19312bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
19322bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
19332bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
19342bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
19352bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
19362bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
19372bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
19382bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
19397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
19407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
19417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1942f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1943f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1944f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1945f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1946f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1947f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1948f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1949f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1950f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1951f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1952f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1953f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1954ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1955ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1956584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1957584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1958584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1959584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1960584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1961a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1962a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1963a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1964a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1965a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
19666029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1967862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1968862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1969862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1970862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
19717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
19727636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
19737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
19747636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
19757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
19767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1977460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1978460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1979460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1980460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1981460a90540b045c102012da2492999557e6840526Jim Grosbach
1982460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1983460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1984460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1985460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1986460a90540b045c102012da2492999557e6840526Jim Grosbach
1987460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1988460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1989460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1990460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1991460a90540b045c102012da2492999557e6840526Jim Grosbach
19920e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
19930e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19940e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19950e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
19960e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19970e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
19980e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
19990e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
2000ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
2001ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
2002ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
2003ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2004ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
2005ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
2006ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
2007ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
2008ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
2009ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
2010ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
2011ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
20126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
20136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
20146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
20156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20166248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
20176248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
20186248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
20196248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
20206248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
20216248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
20226248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
20236248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
20246248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
20256248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
20266248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
20276248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
20286248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
20296248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20306248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
20316248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
20326248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
20336248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
20346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
20356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
20366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
20379b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
20389b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
20399b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach
20409b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
20419b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
20429b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // The immediate encodes the type of constant as well as the value.
20439b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
20449b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    unsigned Value = ~CE->getValue();
20459b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
20469b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
20479b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
20489b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
20499b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffffff)
20509b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 24) | 0x600;
20516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
20526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
20536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
2054f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
2055f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
2056f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
2057f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
2058f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
2059f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
2060f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
2061f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
2062f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
2063f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
2064f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
2065f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
2066b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
2067b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
206889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
206921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
207089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
207189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
207289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
207389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
207489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
207589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
20763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
207721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
2078345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
2079345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
2080345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
20813a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2082345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
2083345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2084fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
208521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
2086fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2087fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2088fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2089fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2090fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2091fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2092fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
209321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
2094fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2095fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2096fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2097fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2098fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2099fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
21009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
21019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
21029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
21039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
21049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
21059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
21069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
21079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2108d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
210921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
2110d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
2111d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
2112d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
2113d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
2114d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
2115d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
21163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
211721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
2118762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
2119762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
2120762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2121762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
21223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
212550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
212621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
2127762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
2128762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2129762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21303a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2133e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
2134e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
2135e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
2136e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
2137e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
213821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
2139af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
2140af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
2141af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
2142af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
2143e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
2144e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
2145e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
2146e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2147e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
214892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
214992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
215092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
215192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
215221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
2153af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
2154af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
2155af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
215692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
215792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
215892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
215992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
216092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
2161580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
21620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
216321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
2164580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
2165580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
21660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
21670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
21680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
21690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
21700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
21717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
217221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
21737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
21747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
21757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
21767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
21777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2179293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
2180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
218121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
2182293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
2183293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
2184293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
2185293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
2186293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
2187293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2188293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
21897729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
21905fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
2191cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
219221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
21930f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
2194d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
219521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
2196d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2197275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
219821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
21990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
22000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
22015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
22027729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
220324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
2204cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
2205cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
2206cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
22078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
22088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
22098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
2210862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
22110aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
2212862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
2213862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
2214862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
22150aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2216862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
2217862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
2218862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
2219862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2220862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
222198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
22223471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                              bool isDoubleSpaced,
222398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
222498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
222598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
222698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
22273471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
222898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
222998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
223098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
223198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
223298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
22337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
223495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             unsigned Index,
223595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             bool isDoubleSpaced,
223695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             SMLoc S, SMLoc E) {
22377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
22387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
22397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
22407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
224195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
22427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
22437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
22447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
22457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
22467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
2247460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
2248460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
2249460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
2250460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
2251460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
2252460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
2253460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
2254460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2255460a90540b045c102012da2492999557e6840526Jim Grosbach
22563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
225721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
2258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
2259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2260762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2262cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2263cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
22647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
22657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
22667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
22677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
22680d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
226957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
22707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
22713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
227221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2273e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2274e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2275e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2276e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2277e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
227857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2279e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
22807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
22817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
22827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
22837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
228416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2285f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2286f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2287f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
22887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
228921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
22907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2291f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2292f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2293f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2298706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
230021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2301706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2302706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2303706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2304706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2305706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2306a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2307a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
230821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2309a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2310a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2311a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2312a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2313a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
231621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2326b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2327fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
232821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
23296a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2330fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
233121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2332d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2333d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
233421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
2335032f441afcdd70eb6bda477d32e8c372443b4e6fCraig Topper    static const char *const MaskStr[] = {
23361a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
23371a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
23381a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
233989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
234089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
234189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
234289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
234321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2344fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2345fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
234621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2347fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2348fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
23499b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
23509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
23519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
235221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
235521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2356fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2357fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
235821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2359706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2360706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
236121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
23626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2363e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
23646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2365fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
236621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2367f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2368f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2369f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2370f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2371f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2372f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
23737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
237421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2375a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2376a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2377a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2378a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2379a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2380a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2381a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2382a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
238321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
238450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2385fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
238621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2387580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2388580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2389e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
239021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
239192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2392efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2393efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2394efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
23950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
239621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
239792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2398efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2399efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2400efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
240192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
240221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
24037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
24047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
240521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2406293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2407293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2408293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
240921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
241021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
241121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
24128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
24138d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
24145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
24155fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
24167729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
24177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
24187729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
24198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
24208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
24218d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
24228d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
24238d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2424862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2425862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2426862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2427862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
242898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
242998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
243098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
243198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
24327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
24337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
24347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
24357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
243621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2437fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2438fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2439460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2440460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2441460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2442fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2443fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
24443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
24453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
24463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
24473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
24483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
24493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
24503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
24513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
245269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
245369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2454a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
24551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2456a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2457bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2458bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2459bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2460bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
24619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2462e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2463e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
24643a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
24651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
246618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
24677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2468d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2469590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
24700c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
24710c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
24720c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
24730c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
24740c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
24750c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
24760c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
247740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
247840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
247940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
248040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
248140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
248240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
248340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
248440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
248540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
248640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
248740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
248840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
248940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
249040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
249140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
249240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
24930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
24940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2495a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2496aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // Check for aliases registered via .req. Canonicalize to lower case.
2497aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // That's more consistent since register names are case insensitive, and
2498aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // it's how the original entry was passed in from MC/MCParser/AsmParser.
2499aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
2500a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2501a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2502a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2503a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2504a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2505a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
250669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2507b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2508460a90540b045c102012da2492999557e6840526Jim Grosbach
2509e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2510e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2511d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
251219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
251319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
251419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
251519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
251619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
25170d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
25180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
25190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
25200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
25210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
25220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2523590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
25240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2525af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
25260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
25270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
25280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
25290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
25300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
25310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
25320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
25330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
253419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
25350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2536e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2537e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2538e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2539e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2540e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2541eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2542e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2543e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2544e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2545e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2546e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2547e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2548e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2549e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2550e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2551e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2552e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2553e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
25548a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
25558a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2556e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2557e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2558e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
255919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
256019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
256119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
256219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2563e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2564e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
256519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
256619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
256719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
256819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2569e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2570e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2571e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2572e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2573e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2574e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2575e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
257619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
257719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2578e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2579de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // shift by zero is a nop. Always send it through as lsl.
2580de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // ('as' compatibility)
2581de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      if (Imm == 0)
2582de626ad8726677328e10dbdc15011254214437d7Jim Grosbach        ShiftTy = ARM_AM::lsl;
2583e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
25841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2585e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
258619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
258719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
258819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
258919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
259019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
259119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2592e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
259319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
259419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2595e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2596e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
259792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
259892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2599af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
26000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
260192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
260292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
260392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
26040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
260519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
26060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
26070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
26080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
260950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
261050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
261150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2612e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2613e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2614e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
261550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
26161355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2617e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
26181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2619e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
262050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2621d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
262250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2624e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2625e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
262650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
262750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2628e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2629460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2630460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2631460a90540b045c102012da2492999557e6840526Jim Grosbach
2632460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2633460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2634460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2635460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2636460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2637460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2638460a90540b045c102012da2492999557e6840526Jim Grosbach
2639460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2640460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
264124dda217052b48373ed89d043a778aabb2f65080Jim Grosbach      return true;
2642460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2643ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (!MCE)
2644ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return TokError("immediate value expected for vector index");
2645460a90540b045c102012da2492999557e6840526Jim Grosbach
2646460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2647ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
2648ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return Error(E, "']' expected");
2649460a90540b045c102012da2492999557e6840526Jim Grosbach
2650460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2651460a90540b045c102012da2492999557e6840526Jim Grosbach
2652460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2653460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2654460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
265599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
265699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
265750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2658a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2660fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2661fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2662fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2664e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2665e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2666e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
26674d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default: return -1;
2668e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2669fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2670e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2671e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2672e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2673e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2674e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2675e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2676e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2677e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2678e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2679e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2680e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2681e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2682e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2683e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2684e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2685fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2686e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2687e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2688e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2689e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2690e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2691e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2692e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2693e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2694e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2695e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2696e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2697e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2698e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
269989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
270089df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
270189df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
270289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
270389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
270489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
270589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
270604a09a461beb4ec629fe53e601b7665547ac35c3Richard Barton  unsigned CC = StringSwitch<unsigned>(Tok.getString().lower())
270789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
270889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
270989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
271089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
271189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
271289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
271389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
271489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
271589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
271689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
271789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
271889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
271989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
272089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
272189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
272289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
272389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
272489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
272589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
272689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
272789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
272889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
272989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
273089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
273189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
273289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
273389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
273443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2737f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
273843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2739e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2740e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2741c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2742c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2743e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2744fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2745e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2746f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2747e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2748e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2749fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2750f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2751fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2752fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
275343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2754fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2755fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2756f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
275743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2758fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2759fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2760c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2761c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2762fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2763fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2764fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2765f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2766fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2767fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2768fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2769f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2770e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2771e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
27729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
27739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
27749b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
27759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
27769b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
27779b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27789b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
27799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
27809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
27819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
27829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27839b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
27849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
27859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
27869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
27879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
27909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
27919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
27929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
27959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
27979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
27989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
28009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
28019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
28029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
28039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
28049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
28059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2806d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2807d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2808d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2811d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2812d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2813d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2814d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2815d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2816bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid GPR number!");
2817d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2818d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2819d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2820d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2821d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2822d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2823d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2824d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2825d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2826d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2827d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2828ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2829ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2830ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2831ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2832ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2833ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2834ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2835ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2836ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2837ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2838ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2839ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2840ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
284125e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2842ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2843ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2844ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2845ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2846ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2847ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2848ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2849ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2850ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2851d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
285250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
28531355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
285418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2855a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2856e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2857d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2858d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
285916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2860d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2861d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2862d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2863d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2864d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2865d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2866ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2867ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2868ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2869ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2870ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2871ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2872ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2873ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2874ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2875ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
28761a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2877d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2878d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2879d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2880d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2881d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2882d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2883d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2884d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2885e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2886ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2887d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2888d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2889d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2890d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2891d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2892d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2893d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2894d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2895e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2896d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2897d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2898d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2899d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2900ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2901ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2902ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2903d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2904d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2905d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2906d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2907d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2908d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2909d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2910d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2911df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher      if (MRI->getEncodingValue(Reg) > MRI->getEncodingValue(EndReg))
2912d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2913d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2914d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2915d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2916d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2917d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2918d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2919d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2920d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2921d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2922d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2923d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2924a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2925d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2926d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
29272d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2928ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2929ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2930ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2931ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2932ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2933ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2934d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2935d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2936d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2937d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2938df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    if (MRI->getEncodingValue(Reg) < MRI->getEncodingValue(OldReg)) {
2939be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach      if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2940be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach        Warning(RegLoc, "register list not in ascending order");
2941be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach      else
2942be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach        return Error(RegLoc, "register list not in ascending order");
2943be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach    }
2944df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
2945a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2946a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2947a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2948a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2949d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2950d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2951d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2952d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2953d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2954d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2955d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2956ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2957ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2958d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2959d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2960d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2961d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2962d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2963d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2964e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
296527debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
296650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
296727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
296827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
296927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
297027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
297127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
297227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
297327debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
297450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2975d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2976d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
297798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
297898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
29797636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
29807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
298198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
298298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
298398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
298498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
298598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
298698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
298798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
298898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2989ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach
2990ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach    // There's an optional '#' token here. Normally there wouldn't be, but
2991ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach    // inline assemble puts one in, and it's friendly to accept that.
2992ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash))
2993ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach      Parser.Lex(); // Eat the '#'
2994ceee984302a1cf1d659a186cf94149c779866da5Jim Grosbach
2995c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCExpr *LaneIndex;
2996c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    SMLoc Loc = Parser.getTok().getLoc();
2997c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (getParser().ParseExpression(LaneIndex)) {
2998c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "illegal expression");
2999c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
30007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
3001c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
3002c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (!CE) {
3003c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "lane index must be empty or an integer");
3004c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
3005c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
3006c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
3007c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "']' expected");
3008c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
3009c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
3010c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Parser.Lex(); // Eat the ']'.
3011c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    int64_t Val = CE->getValue();
3012c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach
3013c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    // FIXME: Make this range check context sensitive for .8, .16, .32.
3014c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Val < 0 || Val > 7) {
3015c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "lane index out of range");
3016c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
3017c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
3018c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Index = Val;
3019c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    LaneKind = IndexedLane;
3020c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    return MatchOperand_Success;
302198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
302298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
302398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
302498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
302598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
3026862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
3027862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3028862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
302998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
30307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
30315c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
30325c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
30335c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
30345c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
30355c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
30365c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
30375c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
30385c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
30395c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
30405c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
30417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
304298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
304398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
304498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
304598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
304698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
30470aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
304898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
304998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
305098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
30513471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
30523471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
305398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
30547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
30557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
305695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
305795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
30587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
305998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
30605c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
30615c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
30625c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
30635c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
30647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
306598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
306698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
306798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
306898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
306998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
307028f08c93e75d291695ea89b9004145103292e85bJim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3071c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
30720aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
307398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
307498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
307598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
3076c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
3077c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
30783471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
30793471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
308098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
30817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
30827636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
308395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
308495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
30857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
308698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
30875c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
30885c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
30895c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
30905c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
30915c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
30925c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
30935c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
3094862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
3095862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3096862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
3097862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
3098862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3099862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
3100862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
3101862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
3102862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3103862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3104862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
3105276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
3106c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
3107c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
3108c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
3109c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
3110c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
31110aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
31120aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
3113c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
3114c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
3115c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
31167636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
311798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
3118c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
3119e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
3120e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
3121e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
31220aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
31230aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
31240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
31250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
31260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
31270aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
31280aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3129e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
3130e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
3131e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
3132e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
3133e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
3134e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3135e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3136e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
3137e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
3138e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
3139e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
3140e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
3141e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
3142e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
3143e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
3144e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
3145e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
3146e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3147e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3148e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
3149e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
3150e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
3151e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3152e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
315398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
315498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
31557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
31567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
315798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
31587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
315998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
316098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
316198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
316298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
3163e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
3164e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
3165e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
3166e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
3167e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
3168e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
3169862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
3170862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
3171862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
3172862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
3173862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
3174862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
3175862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3176862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3177c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
3178862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
3179862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
3180c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
3181c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
3182c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
3183c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
31840aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
31850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
31860aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
31870aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
31880aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
31890aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
31900aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3191c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
3192c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
3193c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
3194c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
3195c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
3196c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
3197c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
319898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
319998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
32007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
320198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
32027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
320398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
32047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
320598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
320698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
320798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
3208c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
3209c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
32100aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
32110aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
32120aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
32130aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
32140aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
32150aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
32160aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
32170aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
3218862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
3219862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3220862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3221862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
322298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
322398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
32247636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
322598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
32267636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
322798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
32287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
322998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
323098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
323198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
3232862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3233862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3234862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3235862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
3236862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
3237862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3238862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3239862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
3240862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
324198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
324298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
3243c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // Two-register operands have been converted to the
3244c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    // composite register classes.
3245c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (Count == 2) {
3246c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      const MCRegisterClass *RC = (Spacing == 1) ?
3247c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
3248c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3249c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3250c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    }
325128f08c93e75d291695ea89b9004145103292e85bJim Grosbach
32520aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
32530aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
325498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
325598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
3256c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // Two-register operands have been converted to the
3257c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // composite register classes.
32584d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    if (Count == 2) {
32594d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach      const MCRegisterClass *RC = (Spacing == 1) ?
32604d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
32614d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3262c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3263c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    }
326498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
32653471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                            (Spacing == 2),
326698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
326798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
32687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
32697636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
327095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           LaneIndex,
327195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           (Spacing == 2),
327295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           S, E));
32737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
327498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
3275862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
3276862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
3277862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
327843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
3279f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
328043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3281706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3283c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  unsigned Opt;
3284c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3285c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  if (Tok.is(AsmToken::Identifier)) {
3286c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    StringRef OptStr = Tok.getString();
3287c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3288c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()).lower())
3289c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("sy",    ARM_MB::SY)
3290c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("st",    ARM_MB::ST)
3291c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("sh",    ARM_MB::ISH)
3292c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("ish",   ARM_MB::ISH)
3293c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("shst",  ARM_MB::ISHST)
3294c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("ishst", ARM_MB::ISHST)
3295c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("nsh",   ARM_MB::NSH)
3296c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("un",    ARM_MB::NSH)
3297c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("nshst", ARM_MB::NSHST)
3298c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("unst",  ARM_MB::NSHST)
3299c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("osh",   ARM_MB::OSH)
3300c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Case("oshst", ARM_MB::OSHST)
3301c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      .Default(~0U);
3302c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3303c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (Opt == ~0U)
3304c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_NoMatch;
3305706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3306c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    Parser.Lex(); // Eat identifier token.
3307c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  } else if (Tok.is(AsmToken::Hash) ||
3308c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu             Tok.is(AsmToken::Dollar) ||
3309c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu             Tok.is(AsmToken::Integer)) {
3310c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (Parser.getTok().isNot(AsmToken::Integer))
3311c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Parser.Lex(); // Eat the '#'.
3312c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    SMLoc Loc = Parser.getTok().getLoc();
3313c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3314c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    const MCExpr *MemBarrierID;
3315c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (getParser().ParseExpression(MemBarrierID)) {
3316c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Error(Loc, "illegal expression");
3317c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_ParseFail;
3318c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    }
3319c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3320c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(MemBarrierID);
3321c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (!CE) {
3322c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Error(Loc, "constant expression expected");
3323c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_ParseFail;
3324c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    }
3325c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3326c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    int Val = CE->getValue();
3327c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    if (Val & ~0xf) {
3328c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      Error(Loc, "immediate value out of range");
3329c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu      return MatchOperand_ParseFail;
3330c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    }
3331c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu
3332c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    Opt = ARM_MB::RESERVED_0 + Val;
3333c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  } else
3334c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu    return MatchOperand_ParseFail;
3335706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3336706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3337f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3338706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3339706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
334043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3341a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
334243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3343a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3344a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3345a1c7367a5bed459acc88e3ea2a482b4b5dac942aRichard Barton  if (!Tok.is(AsmToken::Identifier))
3346a1c7367a5bed459acc88e3ea2a482b4b5dac942aRichard Barton    return MatchOperand_NoMatch;
3347a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3348a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
33492dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
33502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3351a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
33522dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
33532dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
33542dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
33552dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
33562dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
33572dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
33582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
33592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
33602dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
33612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
33622dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
33632dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
33642dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
33652dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
33662dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3367a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3368a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3370a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3371a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
337443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3375584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
337643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3377584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3378584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3379584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3380584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3381584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3382acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3383acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3384b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    std::string Name = Mask.lower();
3385b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    unsigned FlagsVal = StringSwitch<unsigned>(Name)
33860fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // Note: in the documentation:
33870fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //  ARM deprecates using MSR APSR without a _<bits> qualifier as an alias
33880fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //  for MSR APSR_nzcvq.
33890fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // but we do make it an alias here.  This is so to get the "mask encoding"
33900fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // bits correct on MSR APSR writes.
33910fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //
33920fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // FIXME: Note the 0xc00 "mask encoding" bits version of the registers
33930fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // should really only be allowed when writing a special register.  Note
33940fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // they get dropped in the MRS instruction reading a special register as
33950fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // the SYSm field is only 8 bits.
33960fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      //
33970fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // FIXME: the _g and _nzcvqg versions are only allowed if the processor
33980fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      // includes the DSP extension but that is not checked.
33990fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr", 0x800)
34000fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr_nzcvq", 0x800)
34010fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr_g", 0x400)
34020fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("apsr_nzcvqg", 0xc00)
34030fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr", 0x801)
34040fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr_nzcvq", 0x801)
34050fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr_g", 0x401)
34060fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("iapsr_nzcvqg", 0xc01)
34070fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr", 0x802)
34080fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr_nzcvq", 0x802)
34090fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr_g", 0x402)
34100fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("eapsr_nzcvqg", 0xc02)
34110fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr", 0x803)
34120fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr_nzcvq", 0x803)
34130fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr_g", 0x403)
34140fd4f3c8de07e9cfe2a86093ccada82d64f38bfeKevin Enderby      .Case("xpsr_nzcvqg", 0xc03)
3415f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("ipsr", 0x805)
3416f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("epsr", 0x806)
3417f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("iepsr", 0x807)
3418f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("msp", 0x808)
3419f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("psp", 0x809)
3420f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("primask", 0x810)
3421f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("basepri", 0x811)
3422f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("basepri_max", 0x812)
3423f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("faultmask", 0x813)
3424f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby      .Case("control", 0x814)
3425acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
342618c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3427acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3428acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3429acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3430f49a4092bcf679d1634a8023efc593e98a3e5663Kevin Enderby    if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813)
3431acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3432acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
343318c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3434acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3435acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3436acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3437acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3438acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3439584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3440584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3441584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3442590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3443584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3444584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3445584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3448584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3449584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3450584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3451584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3452584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3453b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3454584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3455584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3456584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3457584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
34584b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3459584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3460584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3461584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3462bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
34634b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3464584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
3465b657a90929867716ca1c7c12d442bb5d32281bd4Jim Grosbach    // cpsr_all is an alias for cpsr_fc, as is plain cpsr.
3466b657a90929867716ca1c7c12d442bb5d32281bd4Jim Grosbach    if (Flags == "all" || Flags == "")
346756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3468584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3469584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3470584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3471584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3472584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3473584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3474584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3475584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3476584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3477584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3478584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3479584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3480584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3481584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3482584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3483584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3484584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
34857784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
34867784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
34877784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
34887784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
34897784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
34907784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
34917784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3492584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3493584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3494584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3495584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3496584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3497584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3498584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3499584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3500a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3501a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3502f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3503f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3504f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3505f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3506f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3507f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3508f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3509f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3510f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3511590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3512590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3513f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3514f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3515f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3516f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3517f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3518f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3519f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
35208a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35218a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3522f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3523f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3524f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3525f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3526f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3527f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3528f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3529f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3530f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3531f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3532f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3533f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3534f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3535f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3536f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3537f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3538f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3539f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3540f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3541f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3542f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3543f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3544f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3545f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3546f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3547f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3548f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3549c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3550c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3551c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3552c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3553c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3554c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3555c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3556c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3557c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3558c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3559c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3560c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3561c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3562c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3563c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3564c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3565c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3566c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3567c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3568c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3569c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3570c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3571c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3572c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3573580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3574580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3575580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3576580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3577580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3578580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3579580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3580580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3581580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3582580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3583580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3584580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3585580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3586580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3587580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3588580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3589580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3590580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3591580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3592580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3593580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3594580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3595580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3596580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3597580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3598580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
35998a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
36008a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3601580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3602580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3603580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3604580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3605580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3606580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3607580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3608580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3609580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3610580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3611580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3612580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3613580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3614580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3615580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3616580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3617580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3618580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3619580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3620580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3621580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3622580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3623580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3624580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
36250afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
36260afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
36270afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
36280afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
36290afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3630580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3631580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3632580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3633580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3634580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3635580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3636580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3637580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3638580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3639580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3640580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3641580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3642580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3643580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3644580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
36457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
36467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
36477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
36487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
36497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
36517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3652326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3653326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
36547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3655326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3656326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
36577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
36587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
36608a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
36618a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
36627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
36637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
36667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
36687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
36697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
36707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
36717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
36747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
36757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
36767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
36807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
36817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
36827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
36837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
36847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
36857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
36867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
36877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
36897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
36907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
36917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
36927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
36937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3694293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3695293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3696293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3697293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
36988a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
36998a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3700293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3701293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3702293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3703293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3704293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3705293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3706293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3707293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3708293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3709293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3710293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3711293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3712293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3713293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3714293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3715293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3716293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3717293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3718293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3719293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3720293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3721293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3722293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3723293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3724293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3725293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3726293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3727293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3728293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3729293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3730293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
37318a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
37328a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3733293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3734293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3735293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3736293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3737293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3738293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3739293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3740293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3741293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3742293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3743293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3744293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3745293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3746293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3747293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3748293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3749293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3750293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3751293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3752293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3753293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3754293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3755293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3756293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3757293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3758293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3759293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3760293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3761293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
37627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
37637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3765f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3766f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3767f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
37687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
37697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
37707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
37717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
37727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
37737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
37747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
377516578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
37767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
37777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
37787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
37797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
37807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
37817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
378216578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
37837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
37847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
37857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
37867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
37877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
37887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
37897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
37907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
37917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
37927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
37937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
37947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3795f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3796f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
37970d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
37980d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
37990d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
38000d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
38010d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3802f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3803f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3804f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
38057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
38067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
38077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
38087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3809251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3810251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3811251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3812251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3813251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3814251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3815251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3816251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3817251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3818251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3819251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3820251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3821251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3822251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3823251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3824251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3825251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
38268a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
38278a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3828251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3829251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3830251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3831251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3832251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3833251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3834251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3835251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3836251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3837251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3838251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3839251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3840251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3841251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3842251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3843251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3844251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3845251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3846251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3847251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3848251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3849251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3850251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3851251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3852251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3853251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3854251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3855251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3856251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3857251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3858251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3859251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3860251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3861251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3862251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3863251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3864251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3865251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3866251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3867251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3868251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3869251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3870251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3871251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3872251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3873251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3874251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3875251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3876251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3877251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3878251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3879251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3880a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3881a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3882a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3883359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3884a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3885a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3886a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3887a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3888a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3889a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3890a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3891a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3892a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3893a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3894a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3895a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3896a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3897a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3898a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3899a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3900359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3901a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3902a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3903a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3904a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3905a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3906a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3907a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3908a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3909a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3910a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3911a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3912a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3913a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3914eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3915eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3916eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3917359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3918eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3919eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3920eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3921eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3922eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3923eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3924eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3925eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3926eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3927eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3928eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3929ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3930ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3931ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3932359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3933ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3934ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3935ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3936ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3937ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3938ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3939ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3940ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3941ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
39421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3943ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3944ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3945359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
39461355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3947ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3948ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3949ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3950ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3951ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3952ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
39537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3954ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3955ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3956ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
39579ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
39589ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39599ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
3960359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
39619ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
39629ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39639ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39649ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
39659ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
39669ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
39679ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
39689ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
39699ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39709ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
39719ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
39729ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3973548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3974548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3975548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3976359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
3977548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3978548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3979548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3980548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3981548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3982548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3983548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3984548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3985548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
39861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3987ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3988ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3989359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
39901355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3991ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3992ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3993ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3994548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3995548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3996548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
39987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
39997b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
40007b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40017b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
4002359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
40037b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
40047b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40057b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
40067b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40077b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40087b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
40097b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40107b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
40117b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
40127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
40137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4015359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
40167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
40177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
4019ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
40217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
40267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
4027ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4028ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
4029ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
40307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
4031ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
4032ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
4033359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
40347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
40357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
4037aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
4038ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
4039ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
40407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
4047aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
40487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
40497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4051359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
40527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
40537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
40557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
40577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
40627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
4063ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4064ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
4065ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
40667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
4067ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
4068ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
4069359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
40707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
40717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4072ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
4073ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
40747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
4075ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
40777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
40787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
40797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
40807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
4081ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4082ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
4083ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
40842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
40852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
40862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4087359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
40882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
40892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
40912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
40922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
40932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
40942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
40962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
40972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
40982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
41002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
410114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
410214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
410314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4104359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
410514605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
410614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
410714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
410814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
410914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
411014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
411114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
411214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
411314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
411414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
411514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
411614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
411714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
4118623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
4119623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
4120623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
4121359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
4122623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
4123623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4124623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
4125623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
4126623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
4127623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
4128623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
4129623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
4130623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
41311122fc40c16785d510025daeb6c72a075f7e2e5bChad Rosier/// cvtThumbMultiply - Convert parsed operands to MCInst.
413288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
413388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
4134359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
413588ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
413688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
413788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
413888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
41391b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
41401b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
41411b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
41421b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
41431b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
41441b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
41451b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
41461b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
41471b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
414888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
414988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
4150623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
4151359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
415212431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
415312431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
415412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
41556029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
415612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
415712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
415812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
415912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
416012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
416112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
416212431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
416312431329d617064d6e72dd040a58c1635cc261abJim Grosbach
4164359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
416512431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
416612431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
416712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
41686029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
416912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
417012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
417112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
417212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
417312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
417412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
417512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
417612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
417712431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
417812431329d617064d6e72dd040a58c1635cc261abJim Grosbach
4179359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
41804334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
41814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
41824334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
41834334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
41844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
41854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
41864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
41876029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
41884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
41894334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
41904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
41914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4192359956dc1be35df4f8179eb14cea617c3ef10dd7Chad Rosiervoid ARMAsmParser::
41934334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
41944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
41954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
41964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
41974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
41984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
41994334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
42004334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
42014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
42026029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
42034334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
42044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
42054334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
42064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4207e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
42089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
420950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
42107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4211762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
421218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4213a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
4214762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
4215b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
4216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
421718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
42181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
42197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
42207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
4221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42220571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
42230571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
42240571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
42257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
42260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
42277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
4228762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
4229b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
4230a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
423257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
423303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
4234fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
4235fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
4236fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
4237fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4238fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
4239fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
4240fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
42417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
42427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
424350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
42447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
42457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
424650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
424757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
424857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
424957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
425057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
425157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
425257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
425357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
425457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
425557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
425657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
425757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
425857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
425957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
426057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
426157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
426257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
426357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
426457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
426557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
4266eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
4267eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4268eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
4269eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
427057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
427157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
427257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
427357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
427457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
427557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
427657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
427757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
427857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
427957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
428057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
428157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
428257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
428357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
428457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
428557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
428657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
428757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
428857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
428957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
429057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
429157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
429257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
429357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
429457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
429557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
429657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
429757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
42986cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
42996cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
43006cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
43018a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
43026cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
43038a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
43046cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
43057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
430650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
43070da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
43087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
43097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
43107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
431105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
43127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
43137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
43147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
43157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
43167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
43177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
43187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
43200da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
43210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
43220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
43230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
43247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
43257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
43267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
43277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
43287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
432905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
43307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
43317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
43327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
433357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
433457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
43377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
43387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
43397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
43407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4341762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
43427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
43449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4345d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
43467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
43477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
43487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
43497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
43507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
43517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
43527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
43537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
43547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
43559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
43577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
43587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
43597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
43607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
43627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
43630d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
43647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
43657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
43660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
43677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
43689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
436916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
43707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
43717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
43727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
43737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
43747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
43757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
43767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
437757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
43787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
43797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4380f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4381f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4382f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4383f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4384f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4385f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
43869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
43889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
43899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4392a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
43937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
43947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
43957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
43967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
439718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
440038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4401af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4402af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
44030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4404a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
44050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4406a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
44070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4408a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
44090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4410a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
44110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4412a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
44137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4414b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4415a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
44167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
44177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
44187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
44197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
44207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
44217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
44228a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
44238a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
44247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
44257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
44269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
44277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
44287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
44297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
44307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
44317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
44327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
44337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
44347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
44357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
44367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
44377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
44387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
44397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
44407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
44417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
44427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4443a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4444a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4446a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
44479d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
44489d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
44499d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
445051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Anything that can accept a floating point constant as an operand
445151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // needs to go through here, as the regular ParseExpression is
445251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // integer only.
445351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  //
445451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // This routine still creates a generic Immediate operand, containing
445551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // a bitcast of the 64-bit floating point value. The various operands
445651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // that accept floats can check whether the value is valid for them
445751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // via the standard is*() predicates.
445851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
44599d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
44609d39036f62674606565217a10db28171b9594bc7Jim Grosbach
44618a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
44628a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
44639d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
44640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
44650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
44660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
44670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
44680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
44690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
44700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
44710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
44720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
44730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
44740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
44750e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
44760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
44770e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
44780e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
44790e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
44809d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
44819d39036f62674606565217a10db28171b9594bc7Jim Grosbach
44829d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
44839d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
44849d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
44859d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
44869d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
44879d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
44889d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
4489ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  SMLoc Loc = Tok.getLoc();
44909d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
449151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
44929d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
44939d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
449451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    IntVal ^= (uint64_t)isNegative << 31;
44959d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
449651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
449751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          MCConstantExpr::Create(IntVal, getContext()),
449851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          S, Parser.getTok().getLoc()));
44999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
45009d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
450151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Also handle plain integers. Instructions which allow floating point
450251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // immediates also allow a raw encoded 8-bit value.
45039d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
45049d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
45059d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
45069d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
4507ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach      Error(Loc, "encoded floating point value out of range");
45089d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
45099d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
451051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    double RealVal = ARM_AM::getFPImmFloat(Val);
451151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
451251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
451351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        MCConstantExpr::Create(Val, getContext()), S,
451451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        Parser.getTok().getLoc()));
45159d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
45169d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
45179d39036f62674606565217a10db28171b9594bc7Jim Grosbach
4518ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  Error(Loc, "invalid floating point immediate");
45199d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
45209d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
452151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
45229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
45239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
45241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4525fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4526762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4527fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4528fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4529fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4530f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4531f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4532fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4533f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4534f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4535f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4536f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4537f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4538fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4540146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4541146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
454250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
454319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
45441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
454550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
45460d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
454719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
45480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
454919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
455019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
45513cbe43fe69680df772d83947ced97ca445861213Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
4552b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    if (Mnemonic == "vmrs" &&
4553b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach        Parser.getTok().getString().equals_lower("apsr_nzcv")) {
45545cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
45555cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
4556b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach      Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S));
45575cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
45585cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4559e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4560e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4561e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
456219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4563758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
456467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
45656284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
456667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4567515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4568515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4569515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4570762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4571515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
457250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4573762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
457450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
457550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
457650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4577a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
45781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4579d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
45801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
45818a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
458263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4583079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4584762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4585b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4586b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach
4587b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Colon)) {
4588b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      bool isNegative = Parser.getTok().is(AsmToken::Minus);
4589b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      const MCExpr *ImmVal;
4590b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      if (getParser().ParseExpression(ImmVal))
4591b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach        return true;
4592b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4593b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      if (CE) {
4594b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach        int32_t Val = CE->getValue();
4595b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach        if (isNegative && Val == 0)
4596b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach          ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
4597b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      }
4598b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4599b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
4600b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach      return false;
460163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4602b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach    // w/ a ':' after the '#', it's just like a plain ':'.
4603b8768dc32df0bf3edfa2777cdef57bb066e54344Jim Grosbach    // FALLTHROUGH
460463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
46059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
46069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
46077597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
46087597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
46097597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
46101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
46119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
46129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46137597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
46147597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
46159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
46169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46177597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
46187597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
46199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
46207597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
46219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
46229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4624a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
46261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
46277597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
46281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
46297597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
46309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
46328a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
46339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
46349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
46369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
46379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
46389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
46399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
46419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
46427597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
46439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
46447597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
46459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
46469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
46479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
46489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
46499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
46509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
46519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
46529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
46539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
46549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
46559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
46569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
46579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
46589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4659352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4660352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4661352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4662badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
466389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
46641355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
46655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
46665f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
466789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
466889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4669352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4670352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4671a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4672352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4673badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4674352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4675352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
46765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
46775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
46785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
46795f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
46805f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
46815f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
46825f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
46836849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
46846849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "fmuls")
4685352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4686badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
46873f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
46883f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4689ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
469071725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
469104d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
46922f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
46933f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
46943f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
46953f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
46963f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
46973f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
46983f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
46993f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
47003f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
47013f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
47023f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
47033f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
47043f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
47053f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
47063f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
47073f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
47083f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
47093f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
47103f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
47113f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
47123f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
47133f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
47143f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
47153f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
471652925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4717345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4718352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4719352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4720352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
472100f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
47225f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
47235f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
47245f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
472567ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
472648171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
47279c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach        Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
47286357caec785268d1e39059d03eb2034dee65467fJim Grosbach        Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" ||
472982509e5c62a99912c636b22e227b810eaf6eda78Evan Cheng        Mnemonic == "vfms" || Mnemonic == "vfnms" ||
4730e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4731352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4732352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4733352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4734352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4735a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4736a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4737a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4738a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4740a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4741a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4742a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4743a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4744a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4745a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4746a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4747a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4748a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4749a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
475089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
475189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
475289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
475389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
475489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
475589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4756352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4757352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
47583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
47593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
47603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
47613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
47623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4763fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
47641355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4765fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4766eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4767eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
47683443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4769eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4770d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4771eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4772d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
477382509e5c62a99912c636b22e227b810eaf6eda78Evan Cheng      Mnemonic == "vfm" || Mnemonic == "vfnm" ||
47743443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4775d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4776d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4777eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4778fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4779eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
47803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4781eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4782eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4783eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4784eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4785ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4786ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
47870780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
47882bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
47892bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
47902bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
47914af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
47924af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
47931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
47943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4795fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
47963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4797fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4798fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4799fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
480063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4801fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4802fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4803badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4804badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4805d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4806d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
480720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
480820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4809d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4810d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4811d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4812d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4813d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4814d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4815d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4816d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4817d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
48188adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4819d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4820d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4821d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4822d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
48233912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
48243912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
48253912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
48263912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
48273912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
48283912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
48293912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
48303912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
483172f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
483220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
483320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
483420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4835f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4836f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4837f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
483872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
483972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
484072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
484120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
4842a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach      ((Mnemonic == "add" &&static_cast<ARMOperand*>(Operands[5])->isReg()) ||
484320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
484472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4845f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4846f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
484720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
484820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
484920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4850f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4851f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
485220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
485320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
485420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
485520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
485620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
485720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
485820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
485912a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // check against T3. If the second register is the PC, this is an
486012a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // alternate form of ADR, which uses encoding T4, so check for that too.
486120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
486220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
486312a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC &&
486420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
486520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
486620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
486720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
486820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
486964944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
487020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
487120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
487220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
487320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
487420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
487520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
487620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
487720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
487820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
487964944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
488064944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
488164944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
488264944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
488364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
488464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
488564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
488664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
488764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
488864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
488964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
489064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
489164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
489264944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
48931de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
489464944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
489564944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
489664944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
489764944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
489864944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
489964944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
490064944f48a1164c02c15ca423a53919682a89074cJim Grosbach
49017f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
49027f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
49037f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
49047f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
49057f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
49067f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
49077f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
49087f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
49097f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
49107f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
49117f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
49127f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
49137f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
49147f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
491564944f48a1164c02c15ca423a53919682a89074cJim Grosbach
491620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4917f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4918f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4919f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4920f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4921f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4922f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4923f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
492472f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
492572f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
4926a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
4927a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach      (static_cast<ARMOperand*>(Operands[4])->isImm() ||
4928a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach       (Operands.size() == 6 &&
4929a23ecc2ba945c9685a76552276e5f6f41859b4abJim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm())))
493072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
49313912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4932d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4933d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4934d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
49357aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
49367aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
49377aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
49387aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
49397aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
49407aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
49417aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
49427aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
49437aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
49447aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
49457aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
49467aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
49477aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
49487aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
49497aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
49507aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
495121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4952badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4953badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4954badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
495521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
495621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
495721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
495821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
495921d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
496021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
496121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
496221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4963a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4964a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4965a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4966a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4967a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4968a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4969a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4970a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4971a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4972badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4973badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4974ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4975badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4976352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4977352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4979352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
498089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
49811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
498289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4983badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
49840c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
49850c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
49860c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
49870c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
49880c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
49890c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4990ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4991ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
499289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
499389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
499489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
499589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
499689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
499789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4998f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4999f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
5000f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
5001f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
5002f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
500389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
500489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
500589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
500689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
500789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
5008f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
500989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
501089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
501189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
501289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
501389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
5014f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
501589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
501689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
5017ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
5018ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
50199717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
50203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
50213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
50223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
50233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
50243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
50253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
50263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
50273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
50281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
50293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
503033c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
503133c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
503233c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
503333c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
5034ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
503533c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
503633c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
5037c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
5038c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
5039c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
5040c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
5041c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
5042c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
5043c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
504433c16a27370939de39679245c3dff72383c210bdJim Grosbach
50453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
5046f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
5047f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
50483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
5049f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
5050f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
50513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
50523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
50533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
5054f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
5055f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
50563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
5057f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
5058badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
5059345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
5060a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
5061a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
5062a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
5063a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
5064a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
5065a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
5066a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
5067345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
50685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
50695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
50705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
5071a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
5072a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
50737aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
50747aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
50757aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
50767aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
50777aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
50787aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
507981d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
508081d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
508181d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
508281d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
50835747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
50845747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
50855747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
50865747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5087a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
50881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
5089cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
5090cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
5091cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
5092a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5093a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
5094b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
5095a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5096a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
50971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
5098cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
5099cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
5100cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
5101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
5102a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
510316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
5104cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5105186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
5106cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
5107186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
5108cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
5109146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
511034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
5111ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
5112d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
5113d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
5114d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
511520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
511620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
511720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
511820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
511920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
5120ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5121ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
5122ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
5123ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
5124ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
5125cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
5126cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
5127cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
512821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
512921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
5130cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
5131cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
5132cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5133cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
5134cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
5135cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
5136857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
5137857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
5138857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
5139857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
5140857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
5141857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
5142857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5143857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5144857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
5145857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
5146857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
5147857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
514868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
514968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
515068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
515168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
515268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
515368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
515468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
515568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
515668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
515768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
515868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5159857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
5160857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
5161857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
5162934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
516355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
516455b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
5165934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
516655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
516755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
5168934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5169934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5170934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
517155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
517255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
5173d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
5174d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
5175d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
517655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
5177d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
5178934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
5179934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5180934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
5181934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
5182934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
5183934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
51849898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
5185ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5186ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5187189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
5188aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
5189aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
5190aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
5191aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
5192aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
5193aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
5194aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
5195aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
5196aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
5197aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
5198aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
5199aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
5200aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
5201aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
5202aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
5203aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
5204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
5205aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
520676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
520776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
520876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
520976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
521076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
521176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
521276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
521376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
521476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
521576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
521676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
5217f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
5218f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
5219f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
5220f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
52211a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
52231a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
5224f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
5225f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
5226f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5227189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
5228189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
5229189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
5230189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
52311a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
5232f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
5233f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
523474423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // NOTE: BKPT instruction has the interesting property of being
523574423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // allowed in IT blocks, but not being predicable.  It just always
5236b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
523774423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT &&
523874423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      Inst.getOpcode() != ARM::BKPT) {
5239f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
5240f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
5241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
5242f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
5243a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
5244f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
5245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
5246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
5247f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
5248f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
5249f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
5250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
5251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
5252f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
5253f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
5254f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
5255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
5256f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
5257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
5258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
5259f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
5260f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
5261c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
5262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
5263f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
526451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
526551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
5266f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
5267f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5268189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
52692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
52702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
52712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
5272189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
5273189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5274df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
5275df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
5276189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
5277189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5278189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
5279189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5280189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
528114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
528214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
5283df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt = MRI->getEncodingValue(Inst.getOperand(0).getReg());
5284df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(1).getReg());
528514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
528614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
528714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
528814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
528914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
529053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
529153642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
5292189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
5293189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5294df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt = MRI->getEncodingValue(Inst.getOperand(1).getReg());
5295df1c637ac4b6f6587c037be55cafed665c732d8fEric Christopher    unsigned Rt2 = MRI->getEncodingValue(Inst.getOperand(2).getReg());
5296189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
529714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5298189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
5299189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5300189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5301fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
5302fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
5303fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
5304fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
5305fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
5306fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
5307fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
5308fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
530900c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
5310fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
531193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
531276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
531376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
531476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
531576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
531676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
531793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
531893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
531993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
53207260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
53217260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
53227260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
5323aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
532476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
5325aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
5326aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
532793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
532876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
532993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
533093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
533176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
533276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
5333aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
53347260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
53357260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
53367260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
533793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
533893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
533993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
534076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
534176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
534276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
534376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
534476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
534576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
534676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
534764b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier  case ARM::tMUL: {
534864b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    // The second source operand must be the same register as the destination
534964b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    // operand.
535064b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    if (Operands.size() == 6 &&
535164b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier        (((ARMOperand*)Operands[3])->getReg() !=
535264b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier         ((ARMOperand*)Operands[5])->getReg()) &&
535364b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier        (((ARMOperand*)Operands[3])->getReg() !=
535464b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier         ((ARMOperand*)Operands[4])->getReg())) {
5355fafa283e65bca1473eace94057077129a76dbdccChad Rosier      return Error(Operands[3]->getStartLoc(),
5356fafa283e65bca1473eace94057077129a76dbdccChad Rosier                   "destination register must match source register");
535764b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    }
535864b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier    break;
535964b3444cbf7f5976502ff4cf6fc89aed4986b59cChad Rosier  }
53605402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
53615402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
53625402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
53636dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5364aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
53655402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
53665402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5367aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5368aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
53696dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
53706dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
53716dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5372aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
53735402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
53745402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5375aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5376aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
53776dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
53786dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
53791e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
53801e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
53818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
53821e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
53831e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
53841e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
53851e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5386a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  case ARM::tADDrSP: {
5387a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // If the non-SP source operand and the destination operand are not the
5388a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // same, we need thumb2 (for the wide encoding), or we have an error.
5389a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    if (!isThumbTwo() &&
5390a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach        Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
5391a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      return Error(Operands[4]->getStartLoc(),
5392a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach                   "source register must be the same as destination");
5393a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    }
5394a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    break;
5395a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  }
5396189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5397189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5398189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5399189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5400189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5401d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
540284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
5403bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
54049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
54057945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
54067945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
54077945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
54087945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
54097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
54107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
54117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_8:  Spacing = 1; return ARM::VST1LNd8;
54127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
54137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
54149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
54167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
54177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
54187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
54197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
54207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
54217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
54227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
54237945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
54247945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
54257945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
54267945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
54277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
54287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_8:  Spacing = 1; return ARM::VST2LNd8;
54297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
54307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
54317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
54327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
5433d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
54344adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  // VST3LN
54357945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
54367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
54377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
54387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
54397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
54407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
54417945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
54427945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
54437945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
54447945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
54457945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_8:  Spacing = 1; return ARM::VST3LNd8;
54467945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
54477945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
54487945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
54497945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
54504adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
5451d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3
54527945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
54537945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
54547945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
54557945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
54567945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
54577945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
54587945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
54597945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
54607945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
54617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
54627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
54637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
54647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_8:  Spacing = 1; return ARM::VST3d8;
54657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
54667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
54677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_8:  Spacing = 2; return ARM::VST3q8;
54687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
54697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
5470539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
547188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  // VST4LN
547288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
547388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
547488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
547588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
547688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
547788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
547888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
547988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
548088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
548188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
548288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:  Spacing = 1; return ARM::VST4LNd8;
548388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
548488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
548588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
548688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
548788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
5488539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4
5489539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5490539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5491539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5492539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5493539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5494539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5495539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5496539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5497539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5498539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5499539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5500539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5501539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:  Spacing = 1; return ARM::VST4d8;
5502539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
5503539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
5504539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:  Spacing = 2; return ARM::VST4q8;
5505539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
5506539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
550784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
550884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
550984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
5510d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
55117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
5512bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
55139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
55147945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
55157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
55167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
55177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
55187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
55197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
55207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_8:  Spacing = 1; return ARM::VLD1LNd8;
55217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
55227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
55239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
55257945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
55267945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
55277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
55287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
55297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
55307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
55317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
55327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
55337945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
55347945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
55357945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_8:  Spacing = 1; return ARM::VLD2LNd8;
55367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
55377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
55387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
55397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
55403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
55415e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP
55425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
55435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
55445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
55455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
55465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPq16_UPD;
55475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
55485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
55495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
55505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
55515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
55525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
55535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
55545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:  Spacing = 1; return ARM::VLD3DUPd8;
55555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
55565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
55575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
55585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
55595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
55605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
55613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  // VLD3LN
55627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
55637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
55647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
55657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
55667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
55677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
55687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
55697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
55707945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
55717945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
55727945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_8:  Spacing = 1; return ARM::VLD3LNd8;
55737945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
55747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
55757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
55767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
5577c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
5578c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3
55797945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
55807945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
55817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
55827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
55837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
55847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
55857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
55867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
55877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
55887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
55897945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
55907945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
55917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_8:  Spacing = 1; return ARM::VLD3d8;
55927945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
55937945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
55947945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;
55957945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
55967945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
55978abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
5598e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  // VLD4LN
5599e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5600e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5601e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5602e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNq16_UPD;
5603e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5604e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5605e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5606e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5607e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
5608e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5609e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:  Spacing = 1; return ARM::VLD4LNd8;
5610e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
5611e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
5612e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
5613e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
5614e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
5615a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP
5616a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5617a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5618a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5619a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
5620a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
5621a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5622a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5623a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5624a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5625a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
5626a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
5627a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5628a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:  Spacing = 1; return ARM::VLD4DUPd8;
5629a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
5630a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
5631a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
5632a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
5633a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
5634a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
56358abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  // VLD4
56368abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
56378abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
56388abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
56398abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
56408abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
56418abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
56428abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
56438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
56448abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
56458abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
56468abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
56478abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
56488abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8;
56498abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
56508abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
56518abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8;
56528abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
56538abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
56547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
56557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
56567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
565783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5658f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5659f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5660f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
56610b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  // Aliases for alternate PC+imm syntax of LDR instructions.
56620b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRpcrel:
56630b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRpci);
56640b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56650b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRBpcrel:
56660b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRBpci);
56670b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56680b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRHpcrel:
56690b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRHpci);
56700b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56710b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSBpcrel:
56720b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSBpci);
56730b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56740b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSHpcrel:
56750b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSHpci);
56760b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
56779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
56788b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
56798b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
56808b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32: {
568184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
568284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
568384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
56845b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5685d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
568684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
568784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
568884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
568984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
569084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
569184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
569284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
569384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
569484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
569584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
569684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
56979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56988b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
56998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
57008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
57018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
57028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32: {
57039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
57049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
57065b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5707d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
57099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
57129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57135b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57145b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
57159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
57179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
57189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
57199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
57209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
57214adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
57224adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:
57234adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16:
57244adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32:
57254adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16:
57264adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: {
57274adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
57284adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57294adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
57304adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
57314adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57324adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
57334adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57344adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57354adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
57364adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57374adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57384adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
57394adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57404adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
57414adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57424adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
57434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
57444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
57454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
57464adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
57474adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
574888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:
574988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16:
575088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32:
575188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16:
575288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: {
575388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
575488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
575588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
575688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
575788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
575888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
575988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
576088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
576188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
576288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
576388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
576488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
576588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
576688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
576788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
576888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
576988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
577088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
577188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
577288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
577388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
577488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
577588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
57768b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
57778b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
57788b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: {
577984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
578084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
578184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
57825b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5783d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
578484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
578584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
578684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
578784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
578884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
578984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
579084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
579184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
579284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
579384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
579484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
57959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
57968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
57978b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
57988b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
57998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
58008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: {
58019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
58045b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5805d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
58069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
58109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58115b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58125b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
58139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
58159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
58169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
58179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
58189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
58194adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
58204adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:
58214adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16:
58224adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32:
58234adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16:
58244adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: {
58254adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
58264adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58274adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
58284adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
58294adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
58304adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58314adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58324adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58334adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
58344adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58354adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58364adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
58374adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58384adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
58394adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58404adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
58414adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
58424adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
58434adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
58444adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
58454adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
584688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:
584788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16:
584888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32:
584988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16:
585088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: {
585188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
585288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
585388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
585488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
585588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
585688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
585788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
585888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
585988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
586088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
586188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
586388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
586588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
586788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
586888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
586988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
587088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
587188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
587288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
587388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
58748b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
58758b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
58768b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32: {
587784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
587884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
587984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
58805b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5881d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
588284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
588384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
588484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
588584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
588684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
588784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
588884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
588984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
589084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
58919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58928b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
58938b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
58948b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
58958b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
58968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32: {
58979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
59005b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5901d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
59029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59055b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59065b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
59079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
59119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
59129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
59134adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
59144adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_8:
59154adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_16:
59164adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_32:
59174adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_16:
59184adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_32: {
59194adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
59204adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59214adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
59224adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
59234adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
59244adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59254adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59264adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59274adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59284adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
59294adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59304adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
59314adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59324adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59334adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
593488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
593588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
593688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
593788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
593888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:
593988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16:
594088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32:
594188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16:
594288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: {
594388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
594488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
594588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
594688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
594788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
594888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
594988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
595088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
595188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
595388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
595588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
595688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
595788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
595888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
595988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59604adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
59614adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
59624adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
59634adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
59649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
59658b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
59668b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
59678b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: {
5968872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5969872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5970872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
597195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5972d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5973872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5974872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5975872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5976872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5977872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5978872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5979872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5980872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5981872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5982872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5983872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5984872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
59859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59868b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
59878b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
59888b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
59898b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
59908b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: {
59919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
59929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
599495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5995d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
599795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
599895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
60009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
60039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
600495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
600595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
60089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
60099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
60109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
60119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
60129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
60133a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
60143a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
60153a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
60163a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
60173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: {
60183a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
60193a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
60203a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
60213a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6022d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60233a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60243a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60253a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60263a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6027c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60283a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
60293a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
60323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6036c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
60393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
60403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
60413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
60423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
60433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6044e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:
6045e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16:
6046e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32:
6047e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16:
6048e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: {
6049e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6050e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6051e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6052e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6053e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6054e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6055e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6056e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6057e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6058e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6059e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6060e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6061e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6062e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6063e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6064e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
6065e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6066e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6067e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6068e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6069e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6070e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6071e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6072e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6073e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
6074e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
6075e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6076e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6077e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6078e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
60798b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
60808b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
60818b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: {
6082872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
6083872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
6084872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
608595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6086d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6087872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6088872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6089872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6090872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6091872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6092872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6093872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6094872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6095872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6096872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
6097872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
6098872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
60999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
61008b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
61018b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
61028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
61038b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
61048b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: {
61059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
61069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
61079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
610895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6109d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
611195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
611295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
61139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
61149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
61159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
61169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
611895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
611995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
61209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
61219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
61249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
61259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
61269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
61273a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
61283a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
61293a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
61303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
61313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: {
61323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
61333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
61343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
61353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6136d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6141c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
61433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
61443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
61453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61463a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
61473a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6150c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
61523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
61553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
61563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
61573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6158e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:
6159e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16:
6160e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32:
6161e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16:
6162e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: {
6163e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6164e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6165e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6166e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6167e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6168e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6169e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6170e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6171e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6172e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6173e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6174e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6175e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6176e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6177e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6178e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6179e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6180e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6181e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6182e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6183e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6184e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6185e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6186e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6187e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6188e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6189e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6190e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6191e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6192e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
61938b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
61948b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
61958b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32: {
61967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
61977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
61987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
619995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6200d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
62027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
62037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
62047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
62057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
62067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62077636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62087636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
62097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
62107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
62119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
62128b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
62138b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
62148b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
62158b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
62168b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32: {
62179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
62189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
62199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
622095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6221d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
622395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
622495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
62259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
62269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
62279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
622895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
622995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
62309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
62319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
62349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
62359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
62363a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
62373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
62383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
62393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
62403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
62413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32: {
62423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
62433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
62443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
62453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6246d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62473a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
62483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
62503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6251c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
62523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
62533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
62543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
62553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
62573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6258c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
62593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
62603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
62633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
62643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
62653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6266e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:
6267e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16:
6268e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32:
6269e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16:
6270e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: {
6271e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6272e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6273e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6274e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6275e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6276e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6277e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6278e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6279e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6280e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6281e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6282e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6283e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6284e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6285e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6286e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6287e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6288e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6289e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6290e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6291e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6292e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6293e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6294e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6295e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6296e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6297e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6298e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
62995e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP single 3-element structure to all lanes instructions.
63005e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:
63015e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16:
63025e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32:
63035e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8:
63045e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16:
63055e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: {
63065e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
63075e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
63085e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63095e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63105e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63115e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
63125e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63135e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
63145e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63155e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63165e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63175e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63185e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
63195e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
63205e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
63215e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
63225e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:
63235e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16:
63245e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32:
63255e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8:
63265e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16:
63275e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: {
63285e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
63295e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
63305e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63315e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63325e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63335e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
63345e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63355e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
63365e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63375e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
63385e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63395e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
63405e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63415e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
63435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
63445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
63455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
63465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:
63475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16:
63485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32:
63495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8:
63505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16:
63515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: {
63525e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
63535e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
63545e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
63585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
63605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63615e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
63625e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63635e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
63645e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
63655e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
63665e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
63675e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
63685e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
63695e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
6370c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3 multiple 3-element structure instructions.
6371c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_8:
6372c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_16:
6373c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_32:
6374c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_8:
6375c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_16:
6376c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_32: {
6377c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6378c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6379d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6380c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6381c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6382c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6383c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6384c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6385c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6386c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6387c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6388c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6389c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6390c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6391c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6392c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6393c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:
6394c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16:
6395c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32:
6396c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:
6397c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16:
6398c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: {
6399c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6400c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6401d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6402c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6403c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6404c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6405c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6406c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6407c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6408c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6409c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6410c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6411c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6412c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6413c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6414c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6415c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6416c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6417c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:
6418c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_16:
6419c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_32:
6420c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:
6421c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_16:
6422c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: {
6423c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6424c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6425d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6426d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6427d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6428d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6429d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6430d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6431d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6432d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6433d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6434d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6435d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6436d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6437d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6438d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6439d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6440d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6441a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP single 3-element structure to all lanes instructions.
6442a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:
6443a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16:
6444a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32:
6445a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8:
6446a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16:
6447a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: {
6448a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6449a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6450a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6451a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6452a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6453a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6454a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6455a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6456a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6457a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6458a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6459a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6460a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6461a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6462a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6463a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6464a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6465a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6466a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:
6467a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16:
6468a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32:
6469a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8:
6470a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16:
6471a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: {
6472a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6473a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6474a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6475a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6476a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6477a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6478a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6479a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6480a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6481a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6482a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6483a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6484a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6485a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6486a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6487a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6488a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6489a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6490a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6491a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6492a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:
6493a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16:
6494a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32:
6495a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8:
6496a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16:
6497a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: {
6498a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6499a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6500a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6501a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6502a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6503a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6504a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6505a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6506a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6507a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6508a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6509a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6510a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6511a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6512a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6513a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6514a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6515a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6516a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6517a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6518a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4 multiple 4-element structure instructions.
65198abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:
65208abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16:
65218abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32:
65228abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:
65238abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16:
65248abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: {
65258abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
65268abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
65278abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
65288abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
65298abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65308abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
65318abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65328abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
65338abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65348abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
65358abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65368abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
65378abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
65388abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
65398abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
65408abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
65418abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
65428abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
65438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:
65448abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16:
65458abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32:
65468abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:
65478abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16:
65488abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: {
65498abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
65508abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
65518abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
65528abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
65538abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65548abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
65558abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65568abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
65578abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65588abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
65598abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65608abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
65618abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
65628abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
65638abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
65648abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
65658abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
65668abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
65678abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
65688abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
65698abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:
65708abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16:
65718abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32:
65728abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:
65738abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16:
65748abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: {
65758abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
65768abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
65778abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
65788abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
65798abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65808abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
65818abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65828abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
65838abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
65848abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
65858abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
65868abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
65878abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
65888abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
65898abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
65908abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
65918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
65928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
65938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
65948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
6595d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3 multiple 3-element structure instructions.
6596d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_8:
6597d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_16:
6598d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_32:
6599d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_8:
6600d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_16:
6601d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_32: {
6602d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6603d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6604d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6605d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6606d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6607d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6608d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6609d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6610d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6611d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6612d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6613d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6614d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6615d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6616d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6617d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6618d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:
6619d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16:
6620d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32:
6621d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:
6622d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16:
6623d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: {
6624d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6625d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6626d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6627d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6628d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6629d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6630d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6631c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6632c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6633c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6634c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6635c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6636d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6637d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6638d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6639d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6640d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6641d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6642d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_8:
6643d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_16:
6644d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_32:
6645d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_8:
6646d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_16:
6647d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_32: {
6648d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6649d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6650d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6651c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6652c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6653c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6654c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6655d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6656d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6657d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6658d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6659d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6660c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6661c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6662c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6663c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6664c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6665c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6666539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4 multiple 3-element structure instructions.
6667539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:
6668539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16:
6669539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32:
6670539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:
6671539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16:
6672539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: {
6673539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6674539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6675539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6676539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6677539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6678539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6679539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6680539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6681539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6682539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6683539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6684539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6685539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6686539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6687539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6688539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6689539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6690539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6691539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:
6692539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16:
6693539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32:
6694539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:
6695539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16:
6696539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: {
6697539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6698539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6699539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6700539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6701539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6702539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6703539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6704539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6705539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6706539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6707539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6708539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6709539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6710539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6711539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6712539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6713539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6714539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6715539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6716539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6717539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:
6718539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16:
6719539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32:
6720539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:
6721539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16:
6722539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: {
6723539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6724539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6725539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6726539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6727539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6728539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6729539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6730539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6731539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6732539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6733539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6734539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6735539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6736539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6737539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6738539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6739539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6740539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6741539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6742539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6743a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  // Handle encoding choice for the shift-immediate instructions.
6744a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  case ARM::t2LSLri:
6745a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  case ARM::t2LSRri:
6746a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  case ARM::t2ASRri: {
6747a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6748a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
6749a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach        Inst.getOperand(5).getReg() == (inITBlock() ? 0 : ARM::CPSR) &&
6750a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach        !(static_cast<ARMOperand*>(Operands[3])->isToken() &&
6751a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w")) {
6752a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      unsigned NewOpc;
6753a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      switch (Inst.getOpcode()) {
6754a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      default: llvm_unreachable("unexpected opcode");
6755a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      case ARM::t2LSLri: NewOpc = ARM::tLSLri; break;
6756a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      case ARM::t2LSRri: NewOpc = ARM::tLSRri; break;
6757a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      case ARM::t2ASRri: NewOpc = ARM::tASRri; break;
6758a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      }
6759a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      // The Thumb1 operands aren't in the same order. Awesome, eh?
6760a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      MCInst TmpInst;
6761a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.setOpcode(NewOpc);
6762a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
6763a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
6764a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
6765a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
6766a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6767a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
6768a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      Inst = TmpInst;
6769a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach      return true;
6770a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach    }
6771a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach    return false;
6772a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach  }
6773a5378ebe7890aa9a4974f2872aa6632f1b7f2400Jim Grosbach
6774863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
67752cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVsr:
67762cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVSsr: {
67772cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
67782cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // whether we're in an IT block if the register operands are low
67792cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // registers.
67802cc5cda464e7c936215281934193658cb799c603Jim Grosbach    bool isNarrow = false;
67812cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
67822cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
67832cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(2).getReg()) &&
67842cc5cda464e7c936215281934193658cb799c603Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
67852cc5cda464e7c936215281934193658cb799c603Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
67862cc5cda464e7c936215281934193658cb799c603Jim Grosbach      isNarrow = true;
67872cc5cda464e7c936215281934193658cb799c603Jim Grosbach    MCInst TmpInst;
67882cc5cda464e7c936215281934193658cb799c603Jim Grosbach    unsigned newOpc;
67892cc5cda464e7c936215281934193658cb799c603Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
67902cc5cda464e7c936215281934193658cb799c603Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
67912cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
67922cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
67932cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
67942cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
67952cc5cda464e7c936215281934193658cb799c603Jim Grosbach    }
67962cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.setOpcode(newOpc);
67972cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
67982cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isNarrow)
67992cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
68002cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
68012cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
68022cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
68032cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
68042cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
68052cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (!isNarrow)
68062cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
68072cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
68082cc5cda464e7c936215281934193658cb799c603Jim Grosbach    Inst = TmpInst;
68092cc5cda464e7c936215281934193658cb799c603Jim Grosbach    return true;
68102cc5cda464e7c936215281934193658cb799c603Jim Grosbach  }
6811863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
6812863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
6813863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
6814863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
6815863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
6816863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
6817863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6818863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6819863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
6820863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
6821863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
6822863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
6823863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
6824863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6825863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
6826863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
6827863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
6828863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
6829520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
6830863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
6831d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    unsigned Amount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
6832d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    if (Amount == 32) Amount = 0;
6833863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
6834863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
6835863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
6836863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6837863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6838863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6839520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    if (newOpc != ARM::t2RRX)
6840d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer      TmpInst.addOperand(MCOperand::CreateImm(Amount));
6841863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6842863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6843863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
6844863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6845863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6846863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
6847863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
6848863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
6849863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
685023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
685123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
685223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
685323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
685423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
685523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
685623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
685723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
685823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
685923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
686023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
686123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
686223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
686323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
686423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
686523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
686623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
686723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
686823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
686923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
687023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
687123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
687223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
687323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
687423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
6875ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
6876ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
6877ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
6878ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
6879ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
6880ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
6881ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6882ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
6883ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
6884ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
6885ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
6886ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
6887ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
688848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
6889ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
6890b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    // A shift by 32 should be encoded as 0 when permitted
6891b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
6892b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton      Amt = 0;
6893ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
689471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
6895ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
689671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
689771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6898ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
6899ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
690071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
690171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
690271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
690371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
690483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
690571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
690648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
690748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
690848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
690948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
691048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
691148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
691248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
691348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
691448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
691548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
691648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
691748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
691848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
69190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
69200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
69210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
69220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
69230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
69240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
69250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
69260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
69270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
69280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
69290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
69300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
69310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
69320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
69330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
69340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
69350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
69360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
69370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
69380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
69390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
69400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
69410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
69420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
69430352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
69440352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
69450352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
69460352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
69470352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
69480352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
69490352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
69500352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
6951f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
6952f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
6953f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
6954f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
6955f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
6956f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
6957f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
6958f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6959f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6960f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
6961f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
6962f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
6963f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6964f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6965f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
696683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6967f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
6968f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
6969f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
6970f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
6971f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
6972f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
6973f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
6974f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
6975f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
6976f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6977f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6978f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
6979f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
6980f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6981f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6982f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
6983f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
6984f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
6985da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
6986da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
6987da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
6988da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
6989da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6990da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6991da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
6992da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6993da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
6994da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
6995da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
6996da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
6997da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
6998da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6999da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
7000da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
7001da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
7002da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
700389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
70040f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
70050f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
70060f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
70070f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
7008c0164f86080bc9d7a41fd5eabd0d6556396f5b38Jim Grosbach    if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
700989e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
701083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
701183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
701289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
7013f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
7014f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
7015f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
7016f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
7017f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
7018c0164f86080bc9d7a41fd5eabd0d6556396f5b38Jim Grosbach    if ((unsigned)Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
7019f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
702083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
702183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
7022f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
70232d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach  case ARM::t2ADDri:
70242d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach  case ARM::t2SUBri: {
70252d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // If the destination and first source operand are the same, and
70262d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // the flags are compatible with the current IT status, use encoding T2
70272d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // instead of T3. For compatibility with the system 'as'. Make sure the
70282d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    // wide encoding wasn't explicit.
70292d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
70308f1148bd07d57a1324ed39250642119baa540b7cJim Grosbach        !isARMLowRegister(Inst.getOperand(0).getReg()) ||
70312d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        (unsigned)Inst.getOperand(2).getImm() > 255 ||
70322d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        ((!inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR) ||
70332d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        (inITBlock() && Inst.getOperand(5).getReg() != 0)) ||
70342d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
70352d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
70362d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach      break;
70372d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    MCInst TmpInst;
70382d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.setOpcode(Inst.getOpcode() == ARM::t2ADDri ?
70392d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach                      ARM::tADDi8 : ARM::tSUBi8);
70402d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
70412d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
70422d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
70432d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
70442d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
70452d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
70462d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    Inst = TmpInst;
70472d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach    return true;
70482d30d947ec2626e8b1a9b577cdfa4121f476c3f5Jim Grosbach  }
7049927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
7050927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
7051927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
7052927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
7053927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
7054927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
7055927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
7056713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
7057713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
7058927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
7059927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
7060927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
7061927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
7062927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
7063927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
7064927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
7065927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
7066927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
7067927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
7068927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
7069a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  case ARM::tADDrSP: {
7070a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // If the non-SP source operand and the destination operand are not the
7071a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    // same, we need to use the 32-bit encoding if it's available.
7072a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg()) {
7073a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      Inst.setOpcode(ARM::t2ADDrr);
7074a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
7075a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach      return true;
7076a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    }
7077a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach    break;
7078a9cc08f24f61e2663a131d7ac16c329b75162e7bJim Grosbach  }
707951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
708051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
708183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
708251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
708383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
708483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
708551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
708651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
708751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
708883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
708951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
709083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
709183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
709251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
7093c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
7094a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
709583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
7096c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
709783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
709883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
7099c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
7100395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
7101395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
710283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
7103395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
710483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
710583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
71063ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
710776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
710876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
710976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
711076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
711176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
711276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
711376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
711476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
711576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
711676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
711776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
711876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
711976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
712076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
712176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
712276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
712376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
712476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
712576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
712676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
712776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
712883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
712976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
713076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
713176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
71328213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
71338213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
71348213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
71358213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
71368213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
71378213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
71388213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
71398213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
71408213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
71418213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
714283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
71438213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
71448213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
71458213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
71465402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
71475402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
71485402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
71495402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
71505402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
71515402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
715283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
71535402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
71545402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
71555402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
71565402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
71575402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
715883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
71595402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
71605402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
71615402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
71625402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
716383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
71645402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
71655402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
71665402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
71675402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
71685402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
716983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
71705402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
71711ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
71721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
71731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
71741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
7175c0164f86080bc9d7a41fd5eabd0d6556396f5b38Jim Grosbach        (unsigned)Inst.getOperand(1).getImm() <= 255 &&
7176c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
7177c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
7178c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
71791ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
71801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
71811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
71821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
71831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
71841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
71851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
71861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
71871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
71881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
71891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
719083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
71911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
71921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
71931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
71941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
71951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
71961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
71971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
71981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
71991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
72001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
72011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
72021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
72031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
72041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
72051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
72061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
72071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
72081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
72091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
72101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
721183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
72121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
72131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
72141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
7215326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
721650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
721750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
721850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
7219326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
7220326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
7221326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
7222326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
7223326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
7224326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
7225326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
722650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
722750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
722850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
722950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
723050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
723150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
723250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
723350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
7234326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
7235326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
7236326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
7237326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
7238326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
7239326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
7240326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
7241326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
724283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
7243326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
7244326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
7245326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
724604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  case ARM::MOVsi: {
724704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
7248b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    // rrx shifts and asr/lsr of #32 is encoded as 0
7249b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton    if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
7250b56e4115ed33dae56108ed4ce88ee3a0e0392bfcRichard Barton      return false;
725104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
725204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      // Shifting by zero is accepted as a vanilla 'MOVr'
725304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      MCInst TmpInst;
725404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
725504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
725604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
725704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
725804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
725904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
726004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      Inst = TmpInst;
726104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      return true;
726204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    }
726304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    return false;
726404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  }
72658d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ANDrsi:
72668d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ORRrsi:
72678d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::EORrsi:
72688d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::BICrsi:
72698d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::SUBrsi:
72708d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ADDrsi: {
72718d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    unsigned newOpc;
72728d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
72738d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (SOpc == ARM_AM::rrx) return false;
72748d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    switch (Inst.getOpcode()) {
7275bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("unexpected opcode!");
72768d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
72778d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
72788d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::EORrsi: newOpc = ARM::EORrr; break;
72798d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::BICrsi: newOpc = ARM::BICrr; break;
72808d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
72818d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
72828d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
72838d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    // If the shift is by zero, use the non-shifted instruction definition.
72848ed97ef5f6980c689a5770ec30488601201e17c3Richard Barton    // The exception is for right shifts, where 0 == 32
72858ed97ef5f6980c689a5770ec30488601201e17c3Richard Barton    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0 &&
72868ed97ef5f6980c689a5770ec30488601201e17c3Richard Barton        !(SOpc == ARM_AM::lsr || SOpc == ARM_AM::asr)) {
72878d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      MCInst TmpInst;
72888d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.setOpcode(newOpc);
72898d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
72908d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
72918d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
72928d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
72938d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
72948d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(6));
72958d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      Inst = TmpInst;
72968d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      return true;
72978d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
72988d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    return false;
72998d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  }
730074423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  case ARM::ITasm:
730189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
730289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
730389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
730489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
73054d2f077df1b46a126b5595d983f233ec896b757eRichard Barton    // of the condition code is zero.
730689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
730789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
7308f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
7309f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
731089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
731189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
731289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
731389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
73144d2f077df1b46a126b5595d983f233ec896b757eRichard Barton    }
731589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
7316f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
7317f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
7318f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
7319f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
7320f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
7321f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
7322f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
7323f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
732489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
732589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
73262b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2LSLrr:
73272b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2LSRrr:
73282b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ASRrr:
73292b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2SBCrr:
73302b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2RORrr:
73312b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2BICrr:
73322b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  {
7333c985e6ece66cf2046f0113da9eb2dec331a6b09fRichard Barton    // Assemblers should use the narrow encodings of these instructions when permissible.
73342b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
73352b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         isARMLowRegister(Inst.getOperand(2).getReg())) &&
73362b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
7337874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton        ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) ||
7338874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton         (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) &&
73392b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        (!static_cast<ARMOperand*>(Operands[3])->isToken() ||
73402b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         !static_cast<ARMOperand*>(Operands[3])->getToken().equals_lower(".w"))) {
73412b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      unsigned NewOpc;
73422b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      switch (Inst.getOpcode()) {
73432b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        default: llvm_unreachable("unexpected opcode");
73442b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2LSLrr: NewOpc = ARM::tLSLrr; break;
73452b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2LSRrr: NewOpc = ARM::tLSRrr; break;
73462b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ASRrr: NewOpc = ARM::tASRrr; break;
73472b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2SBCrr: NewOpc = ARM::tSBC; break;
73482b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2RORrr: NewOpc = ARM::tROR; break;
73492b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2BICrr: NewOpc = ARM::tBIC; break;
73502b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      }
73512b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      MCInst TmpInst;
73522b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.setOpcode(NewOpc);
73532b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(0));
73542b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(5));
73552b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(1));
73562b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(2));
73572b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(3));
73582b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(4));
73592b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      Inst = TmpInst;
73602b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      return true;
73612b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    }
73622b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    return false;
73632b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  }
73642b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ANDrr:
73652b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2EORrr:
73662b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ADCrr:
73672b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  case ARM::t2ORRrr:
73682b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  {
7369c985e6ece66cf2046f0113da9eb2dec331a6b09fRichard Barton    // Assemblers should use the narrow encodings of these instructions when permissible.
73702b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    // These instructions are special in that they are commutable, so shorter encodings
73712b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    // are available more often.
73722b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    if ((isARMLowRegister(Inst.getOperand(1).getReg()) &&
73732b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         isARMLowRegister(Inst.getOperand(2).getReg())) &&
73742b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() ||
73752b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg()) &&
7376874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton        ((!inITBlock() && Inst.getOperand(5).getReg() == ARM::CPSR) ||
7377874b863f2ab9158db6f7f1b773b77e6334e31c41Richard Barton         (inITBlock() && Inst.getOperand(5).getReg() != ARM::CPSR)) &&
73782b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        (!static_cast<ARMOperand*>(Operands[3])->isToken() ||
73792b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton         !static_cast<ARMOperand*>(Operands[3])->getToken().equals_lower(".w"))) {
73802b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      unsigned NewOpc;
73812b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      switch (Inst.getOpcode()) {
73822b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        default: llvm_unreachable("unexpected opcode");
73832b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ADCrr: NewOpc = ARM::tADC; break;
73842b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ANDrr: NewOpc = ARM::tAND; break;
73852b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2EORrr: NewOpc = ARM::tEOR; break;
73862b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        case ARM::t2ORRrr: NewOpc = ARM::tORR; break;
73872b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      }
73882b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      MCInst TmpInst;
73892b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.setOpcode(NewOpc);
73902b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(0));
73912b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(5));
73922b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) {
73932b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(1));
73942b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(2));
73952b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      } else {
73962b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(2));
73972b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton        TmpInst.addOperand(Inst.getOperand(1));
73982b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      }
73992b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(3));
74002b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      TmpInst.addOperand(Inst.getOperand(4));
74012b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      Inst = TmpInst;
74022b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton      return true;
74032b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    }
74042b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton    return false;
74052b6652fb10d7005e41010b0e0800afe16ae18a34Richard Barton  }
7406f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
740783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
7408f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
7409f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
741047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
741147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
741247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
7413194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
74141a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
741547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
741647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
741747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
741847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
741947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
742047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
742147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
742247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
742347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
742447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
742547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
742647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
742747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
742847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
742947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
743047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
7431f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
7432f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
743347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
7434f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
7435f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
7436f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
743747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
7438194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
7439194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
7440194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
7441194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
7442194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
7443194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
7444194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
74454ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
7446194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
7447194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
7448194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
744947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
745047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
745147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
745214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbachstatic const char *getSubtargetFeatureName(unsigned Val);
7453fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
7454fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
7455fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7456fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
7457fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
7458fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
745919cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
7460193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
7461193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
746219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
7463e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
7464189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
7465189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
7466a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
7467a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
7468a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
7469a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
7470189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
7471a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
7472189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
7473f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
747483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
747583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
747683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
747783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
747883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
7479f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
7480a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
7481a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
7482a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
7483a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
7484a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
748574423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
748674423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // doesn't actually encode.
748774423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    if (Inst.getOpcode() == ARM::ITasm)
748874423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      return false;
748974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach
749042e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Inst.setLoc(IDLoc);
7491fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
7492fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
749314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  case Match_MissingFeature: {
749414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    assert(ErrorInfo && "Unknown missing feature!");
749514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    // Special case the error message for the very common case where only
749614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    // a single subtarget feature is missing (Thumb vs. ARM, e.g.).
749714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    std::string Msg = "instruction requires:";
749814ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    unsigned Mask = 1;
749914ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
750014ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach      if (ErrorInfo & Mask) {
750114ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach        Msg += " ";
750214ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach        Msg += getSubtargetFeatureName(ErrorInfo & Mask);
750314ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach      }
750414ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach      Mask <<= 1;
750514ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    }
750614ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach    return Error(IDLoc, Msg);
750714ce6fac242228dacc5c08040e544141a96880e5Jim Grosbach  }
7508e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
7509e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
7510e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
7511e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
7512e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
751316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7514e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
7515e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
7516e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
751716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7518e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
7519e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
7520e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
7521362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer    return Error(IDLoc, "invalid instruction",
7522362a05a635379ca1151e5ccf735295aed814dd4bBenjamin Kramer                 ((ARMOperand*)Operands[0])->getLocRange());
7523b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
7524d9b0b025612992a0b724eeca8bdf10b1d7a5c355Benjamin Kramer    // The converter function will have already emitted a diagnostic.
752588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
7526f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
7527f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
752847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
752947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
7530194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
7531194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
7532194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
7533194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
753470c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach  case Match_ImmRange0_15: {
753570c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    SMLoc ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
753670c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
753770c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach    return Error(ErrorLoc, "immediate operand must be in the range [0,15]");
753870c9bf3c1a77b5707c92a7cfe74104c320480391Jim Grosbach  }
7539fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
754016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7541c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
7542fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
7543fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
75441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
7545ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
7546ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
7547ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
75481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
7549515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
75501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
75519a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
75529a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
7553515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
75541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
7555515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
75561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
7557515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
75581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
7559a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
7560a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
7561d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".arch")
7562d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveArch(DirectiveID.getLoc());
7563d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".eabi_attribute")
7564d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveEabiAttr(DirectiveID.getLoc());
7565ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
7566ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7567ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
75681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
7569ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
75701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
7571ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
7572ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
7573ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
7574ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
7575ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
7576ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7577aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
7578ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7579ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
7580ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
758116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7582ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
7583ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
7584ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
7585b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
7586ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
7587ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
7588ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7589b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7590ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
7591ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7592ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
75931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
7594515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
75951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
7596515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
7597515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7598b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7599515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76009a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
76019a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
76029a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
76039a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
76049a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
76059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
76069a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
76079a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
76089a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
76099a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
76109a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
76119a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
76129a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
76139a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
76149a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
76159a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7616515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7617515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7618515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
7620515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
76211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
76226469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
76236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
76246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
7625de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  bool needFuncName = true;
76266469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7627de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Darwin asm has (optionally) function name after .thumb_func direction
76286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
76296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
76306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
7631de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    if (Tok.isNot(AsmToken::EndOfStatement)) {
7632de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
7633de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach        return Error(L, "unexpected token in .thumb_func directive");
7634de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Name = Tok.getIdentifier();
7635de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Parser.Lex(); // Consume the identifier token.
7636de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      needFuncName = false;
7637de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    }
76386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
76396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7640de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
7641515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7642de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach
7643de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Eat the end of statement and any blank lines that follow.
7644de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  while (getLexer().is(AsmToken::EndOfStatement))
7645de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    Parser.Lex();
7646515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
7648de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // We really should be checking the next symbol definition even if there's
7649de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // stuff in between.
7650de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (needFuncName) {
7651d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
76526469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
76536469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7654642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
7655642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
7656642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
7657515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7658515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7659515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
7661515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
76621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
766318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7664515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
7665515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
766638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
766758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
7668b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
766958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
76709e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
7671515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7672515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
7673515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7674515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
767518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7676b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7677515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7678515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
7679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
7680515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
76831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
7684515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
76851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
768618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7687515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
7688515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
768918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
769058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
7691b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
769258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
7693b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
7694515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7695515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
7696515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7697515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
769818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7699b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
770132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
770298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
7703ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
770498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
770532869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
770698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
7707ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
770898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7709eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
77102a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
7711515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7712515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7713515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7714a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
7715a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
7716a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7717a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
7718a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
7719a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
7720a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
7721a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7722a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
7723a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7724a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7725a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
7726a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7727a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7728a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
7729a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
7730a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7731a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7732a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
7733a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7734a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
7735a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
7736a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
7737a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7738a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7739a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7740a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7741a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
7742a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
7743a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
7744a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
7745a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7746a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
7747a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7748a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
7749a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
7750a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7751a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7752a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7753d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch
7754d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .arch token
7755d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) {
7756d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7757d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7758d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
7759d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr
7760d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .eabi_attribute int, int
7761d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
7762d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7763d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7764d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
776590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
776690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
77679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
7768ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
776994b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
777094b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
777190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
7772ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
77733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
77740692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
77758030e1a0df630ec6ed1cd5ec673f6472558a4dbeCraig Topper#define GET_SUBTARGET_FEATURE_NAME
77760692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
77773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
7778