ARMAsmParser.cpp revision be7cf2b377d987f46d10f54f89ae4e1a71c37f55
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h"
2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h"
3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbachenum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
4398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
4494b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
4728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  const MCRegisterInfo *MRI;
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
49a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Map of register aliases registers via the .req directive.
50a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StringMap<unsigned> RegisterReqs;
51a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
68f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
69f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
70f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
71f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
76a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
77a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
78a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
79a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
80f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
81f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
84ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
85ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
86ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
87ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
900d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
999a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
103a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveReq(StringRef Name, SMLoc L);
104a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveUnreq(SMLoc L);
105d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveArch(SMLoc L);
106d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveEabiAttr(SMLoc L);
107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
11089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
112fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
115ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
116ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
117ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
118ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
119ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
120ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
12147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
12247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
124194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
125194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
126194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
127acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
128acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
129acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
13032869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
131ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
132ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
134acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
135acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
136acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
137ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1410692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1420692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
148f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
150f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1548bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1568bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1588bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
166f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
167c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
168580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
170293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
172251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1739d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
174862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
177ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
180a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
181a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
182eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
183eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
184ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
185ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
187ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1899ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
190548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
191548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
193ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1957b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
2052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
20714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
208623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
209623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
21088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
21188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
21212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
21312431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
21412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
21512431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
2164334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2174334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
2184334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2194334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
220189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
222189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
224f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
225d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
226d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
227189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
228ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
22947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
230194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
232194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
233194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
23547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
236ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
23794b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
238ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
23932869205052430f45d598fba25ab878d8b29da2dEvan Cheng
24028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    // Cache the MCRegisterInfo.
24128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    MRI = &getContext().getRegisterInfo();
24228f08c93e75d291695ea89b9004145103292e85bJim Grosbach
243ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
244ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
247f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
248ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
249ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
253189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
25647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
25747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
261ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
26216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
26316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2643a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
266a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
267a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
268146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
27821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
282460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
28421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
28621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
287862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
28898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
29121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
29221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
29321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
29421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
29521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
29924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
3038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
307fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
308fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
309fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
310fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
31589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
31689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
31989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
32089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
32189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
32289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
337a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
338a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
339862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
340862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
341862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
342862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3440aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
345862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
346862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3478155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
348460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
349460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
350460a90540b045c102012da2492999557e6840526Jim Grosbach
351460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
352cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
353cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
35416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3556a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
356a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
357a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
36357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
36457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
365eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
367e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
371f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
372f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
373f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
377580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
378e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
379580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
385af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
38692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
38792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
38892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
38992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
390af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
394293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
395293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
396293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
397293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
39916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
400146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
401146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
403762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
405762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
406762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
40721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
41021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
41189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
41289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
418762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
419762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
42221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
42324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
425862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
42698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4277636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
428862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
429862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
43121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
432fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
433fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
43721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
438762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
439762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
441706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
442706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
44321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
444e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
445762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
44921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
450584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
451584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
45221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
453a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
459af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
46121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
462af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
46392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
46721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
468293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
469293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
470460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
471460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
472460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
476762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
48221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4838462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
48721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
488fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
489fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
490fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
49221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
494a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
49721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4987729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
500a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
50221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
50424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5058d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
50821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    assert(isImm() && "Invalid access!");
509cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
510cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
511cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
512460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
513460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
514460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
515460a90540b045c102012da2492999557e6840526Jim Grosbach  }
516460a90540b045c102012da2492999557e6840526Jim Grosbach
517706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
51821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
519706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
521706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
52321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
527584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
52821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
529584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
531584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
53221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
53621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
53821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
54051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  bool isFPImm() const {
54151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!isImm()) return false;
54251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
54351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!CE) return false;
54451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
54551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    return Val != -1;
54651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  }
5474050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits16() const {
5484050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5494050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5504050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5514050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5524050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 0 && Value <= 16;
5534050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
5544050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits32() const {
5554050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5564050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5574050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5584050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5594050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 1 && Value <= 32;
5604050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
561a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
56221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
563a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
564a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
565a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
566a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
567a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
56872f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
56921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57072f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57172f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57272f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
57372f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
57472f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
57572f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
57621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57972f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
58072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
58172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
58321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
5846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
59021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
591587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
592587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
593587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
594587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
595587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
596587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
59721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
598587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
599587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
600587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
601587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
602587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
60421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
61121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
61283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
61383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
61483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
61583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
61683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
61821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6197c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6207c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6217c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6227c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6237c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
624730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
62521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
626730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
627730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
628730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
629730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
630730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
63221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6353b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
63921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6423b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
64621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6473b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6483b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6493b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6503b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6513b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
65321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6566b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
66021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6636b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
66721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
67421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6766b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6786b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
6796b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
68121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
68821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6913b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
69521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6973b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6983b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6993b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
7003b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
701f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
70221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
703f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
70921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7114a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
715ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
71621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
717ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
718ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
719ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
720ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
721ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
722fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
72321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
724fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
725fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
726fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
727fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
728fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
729ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
73021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
731ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
732ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
733ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
734ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
735ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
736ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
737ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
738ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
73921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
740ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
741ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
742ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
743ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
744ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
74570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
74621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
74770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
74870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
74970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
75070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
75170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
752f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
75321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
756f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
76021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7666bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
76721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7696bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
7706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
7716bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
7726bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
773e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
77421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
775e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
776e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
777e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
778e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
779e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
7803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
78121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7833bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
7843bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
7853bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getSOImmVal(-Value) != -1;
7863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
7876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
78821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
7916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
7926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
7936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
79489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
79521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
79689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
79789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
79889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
79989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
80089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
8013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
80221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
8033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8043bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8063bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getT2SOImmVal(-Value) != -1;
8073bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
80921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
811c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
812c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
813c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
814c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
81521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
81621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
81721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
81821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
81921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
82021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
82121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
82221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
82321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
82421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
82521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
82621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
82721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
828f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
829430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
830f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
83157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
832f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
833ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
83557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
83657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
83757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
8380b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  bool isMemPCRelImm12() const {
8390b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
8400b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8410b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base register must be PC.
8420b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum != ARM::PC)
8430b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8440b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Immediate offset in range [-4095, 4095].
8450b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!Memory.OffsetImm) return true;
8460b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8470b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8480b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
84957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
85057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
851ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
85357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
855e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
857e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
858e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
861039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
86221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
863039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
864039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
865039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
866039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
867039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
868039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
8692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
8702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
8712f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
8722f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
87321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
8742f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
87557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
877e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
8782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
881e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
882e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
8842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
88621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
88821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
8902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
894251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
895251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
8962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
898681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
899681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
900681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
90121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
902681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
90357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
905e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
907e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
908e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9090da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
910681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
913e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9167f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
919e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
92157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9227f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9237f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
92657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
927ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
928ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
930ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
93157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
93257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
933ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
934ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
935e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
937e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
938ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
939ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
940ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
944e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
94557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
94687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
947e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
948e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
94960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
95060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
951e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
95257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
95360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
95460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
955e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
956e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
957ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
958ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
95938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
960e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
96238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
96338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
964e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
965e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
96638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
96738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
96848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
969e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
97148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
97248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
973e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
974e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
97548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
97648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
977ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
97857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
980ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
981ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
982e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
983e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
984ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
985505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
986a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
9872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
9882f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
9892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
99021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
9912f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
99257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
995e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
996e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
997a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
998a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
999b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
100057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1001b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
1003e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1004e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1005b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1006b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
100857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1009f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10100b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10110b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1013e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1014e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10154d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1016f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1017f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
101857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1020f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1021e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1022e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1023f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1024f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1025a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
102657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1027a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
10280b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10290b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1031df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1032e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1033df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1035a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
103657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1037a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1038a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1039e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1040e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1041a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1042a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
104409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
104509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
104609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
104721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
104809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
104909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
105057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1051ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1053e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1054e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10550da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
105821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1060ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
10617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
106263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1063ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
106521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
10682bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
10692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
10702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
10712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
10727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
107321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
107421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
10753483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
10770aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
10780aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
10790aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
10800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
10810aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
10820aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
10840aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1085862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1086862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1087862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
108828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  bool isVecListDPair() const {
108928f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!isSingleSpacedVectorList()) return false;
109028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
109128f08c93e75d291695ea89b9004145103292e85bJim Grosbach              .contains(VectorList.RegNum));
109228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
109328f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1094cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
10950aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1096cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1097cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1098cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1099b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
11000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1101b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1102b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1103b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
1104c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  bool isVecListDPairSpaced() const {
1105c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1106c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
1107c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach              .contains(VectorList.RegNum));
1108c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  }
1109c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1110c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  bool isVecListThreeQ() const {
1111c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
1112c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return VectorList.Count == 3;
1113c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
1114c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
11157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  bool isVecListFourQ() const {
11167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach    return VectorList.Count == 4;
11187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  }
11197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
11203471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isSingleSpacedVectorAllLanes() const {
11213471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
11223471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11233471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isDoubleSpacedVectorAllLanes() const {
11243471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
11253471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
112698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
11273471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
112898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
112998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
113098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
1131c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  bool isVecListDPairAllLanes() const {
11323471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1133c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    return (ARMMCRegisterClasses[ARM::DPairRegClassID]
1134c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach              .contains(VectorList.RegNum));
11353471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11363471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach
11374d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  bool isVecListDPairSpacedAllLanes() const {
11383471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
113913af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
114013af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
114113af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11425e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeDAllLanes() const {
11435e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11445e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11455e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11465e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
11475e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  bool isVecListThreeQAllLanes() const {
11485e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
11495e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return VectorList.Count == 3;
11505e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
11515e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
1152a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourDAllLanes() const {
1153a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
1154a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1155a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1156a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
1157a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  bool isVecListFourQAllLanes() const {
1158a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
1159a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return VectorList.Count == 4;
1160a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
1161a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
116295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isSingleSpacedVectorIndexed() const {
116395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
116495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
116595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isDoubleSpacedVectorIndexed() const {
116695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
116795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
11687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
116995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11707636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
11717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
11727636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1173799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
117495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1175799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1176799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1177799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1178799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
117995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1180799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1181799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1182799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
11839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
118495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
11869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
11879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1188799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
118995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
119095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
119195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
119295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
119395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQWordIndexed() const {
119495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
119595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
119695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
119795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
119895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQHWordIndexed() const {
119995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1200799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1201799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1202799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1203799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
120495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1205799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1206799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1207799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
12083a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDByteIndexed() const {
12093a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12103a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
12113a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12123a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12133a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDHWordIndexed() const {
12143a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12153a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12163a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12183a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQWordIndexed() const {
12193a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12203a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12213a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12223a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12233a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQHWordIndexed() const {
12243a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
12253a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
12263a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12273a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
12283a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDWordIndexed() const {
12293a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
12303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
12313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
12323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
1233e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDByteIndexed() const {
1234e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1235e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 7;
1236e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1237e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1238e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDHWordIndexed() const {
1239e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1240e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1241e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1242e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1243e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQWordIndexed() const {
1244e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1245e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1246e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1247e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1248e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourQHWordIndexed() const {
1249e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1250e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 3;
1251e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1252e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1253e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  bool isVecListFourDWordIndexed() const {
1254e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1255e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return VectorList.Count == 4 && VectorList.LaneIndex <= 1;
1256e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
1257e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
1258460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1259460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1260460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1261460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1262460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1263460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1264460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1265460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1266460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1267460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1268460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1269460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1270460a90540b045c102012da2492999557e6840526Jim Grosbach
12710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
127221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
12750e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
12760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
12770e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
12780e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
12790e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
12800e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1281460a90540b045c102012da2492999557e6840526Jim Grosbach
1282ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
128321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1284ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1285ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1286ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1287ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1288ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1289ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1290ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1291ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
12926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
129321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
12966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
12976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
12986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
12996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
13036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
13056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
130621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
13096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
13106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
13116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
13146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13166248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13176248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13186248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13196248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
13209b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  bool isNEONi32vmovNeg() const {
132121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
13229b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13239b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // Must be a constant.
13249b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (!CE) return false;
13259b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    int64_t Value = ~CE->getValue();
13269b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
13279b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
13289b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    return (Value >= 0 && Value < 256) ||
13299b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
13309b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
13319b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
13329b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
13339b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
13349b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
13356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1336f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
133721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1338f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1339f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1340f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1341f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1342f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1343f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1344f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1345f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1346f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1347f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
13483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
134914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
135014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
135114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
135214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
13533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
13543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
13553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
13563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
13573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
13588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1359345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
13608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
136104f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
136204f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
13638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
13648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
13709b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
13719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13729b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
13739b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13749b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
13759b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
13769b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13779b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
13789b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13799b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
138089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
138189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
138289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
138389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
138489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
138589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
138689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
138789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
138889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
138989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1390d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1391d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1392d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1393d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1394d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1395a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1396a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1397a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1400af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1401e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1402430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1403430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1404af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1405af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1406e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1407af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1408e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1409e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1410af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1411152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1412430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1413430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1414af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
141592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1416af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
141792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
141892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1419580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
14200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1421580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1422580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
14230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
142587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
14267729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
14275fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
14285fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
14297729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
14307729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
143187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
143287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
14330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
14340f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
14380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
14390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
14400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
14427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
14447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
14457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1447293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1448293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1449293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1450293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1451293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1452293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1453293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1454293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1455293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1456293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1457293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
14583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
14596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14606b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
14616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
14626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
14634050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits16Operands(MCInst &Inst, unsigned N) const {
14644050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14654050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14664050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
14674050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14684050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14694050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits32Operands(MCInst &Inst, unsigned N) const {
14704050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14714050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14724050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
14734050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14744050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14759d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
14769d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
147751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
147851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
147951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14809d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
14819d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1482a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1483a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1484a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1485a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1486a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1487a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1488a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1489a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
149072f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
149172f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
149272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
149372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
149472f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
149572f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
149672f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
149772f39f8436848885176943b0ba985a7171145423Jim Grosbach
149872f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
149972f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
150072f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
150172f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
150272f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
150372f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
150472f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
150572f39f8436848885176943b0ba985a7171145423Jim Grosbach
1506f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1507f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1508f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1509f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1510f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1511f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1512f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1513f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
15144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
15154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
15174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
15184a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15194a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
15204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
15214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
152270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
152370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
152470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
152570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
152670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
152770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
152870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1529ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1530ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1531f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1532f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1533f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1534f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1535f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1536f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1537f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1538f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1539f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
154089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
154189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
154289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
154389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
154489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
154589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
154689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
154789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
15483bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
15493bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15503bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
15513bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15523bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15533bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15543bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15553bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1556e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1557e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1558e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1559e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1560e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1561e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1562e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1563e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
15643bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
15653bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15663bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
15673bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15683bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15693bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15703bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15713bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1572706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1573706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1574706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1575706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1576706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
15777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
15787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1579e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1580505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1581505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
15820b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
15830b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15840b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int32_t Imm = Memory.OffsetImm->getValue();
15850b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // FIXME: Handle #-0
15860b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
15870b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
15880b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
15890b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach
159057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
159157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
159257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
159357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
159457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
159557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
15967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
15977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1598e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1599e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
16027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
16047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
16057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
16077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1608e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1609e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1611e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1612e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1615ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1616039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1617039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1618039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1619039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1620039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1621039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1622039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1623039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1624039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1625039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1626039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1627039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1628039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1629039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
16302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
16312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
16322f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
16332f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
16342f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
16352f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
16362f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
16372f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
16382f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
16392f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
16402f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
16412f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1642e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1643e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
16442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
16462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
16472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
16482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
16492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
16502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
16512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1652e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
16532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1654e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1655e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
16602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
166121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
16622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
16632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
16642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
16652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
16672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
16682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
16702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
16712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
16722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
16742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
16772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
16782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
16827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1683681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1684681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1685681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1686681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1687681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1688681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1689681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1690681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1691681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
16927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1693e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
16947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
16967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
16987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1699e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
17027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1703a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1704a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
17052f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
17062f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
17072f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
17082f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
17092f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
17102f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
17112f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
17122f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
17132f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1714e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1715e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1716a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1717a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1718a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1719b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1720b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1721b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1722e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1724b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1725b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1726b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
17277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
17287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1729e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1730e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1732ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1733ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1734f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1735f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1736f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1737f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1738a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1739f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1740a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1741a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1742a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1743a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1744a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
174521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
1746a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1747a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1748a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1749a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1750a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1751a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1752e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1753e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1754a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1755a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1756a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
17577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
17587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
175909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
176021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
176109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
176209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
176309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
176409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
176509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
176609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1767e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1768e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
177192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
17727f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
17737f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1774e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1775e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17767f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17777f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17787f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
17797f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1780e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1781e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17837f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
17857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1786430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1787430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1788430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1789e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1790e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1793d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1794ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1795ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1796e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1797e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1798e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1799ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1800ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
18017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
18027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1803e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1804e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
180514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
18063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
180760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
180860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1809e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
181160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
181248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
181348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
181438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
181538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1816e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1817e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
181838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
181938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
182038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
182148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
182248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1823e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1824e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
182548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
182660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
182760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1828ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1829ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1830e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1831e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1832ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1833ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1834ecd858968384be029574d845eb098d357049e02eJim Grosbach
18357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
18367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
18397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
18407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
184163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
18427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
18437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1844f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1845ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
18462bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
18472bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
18482bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18492bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
18502bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
18512bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
18522bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
18532bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
18542bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
18552bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
18562bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
18572bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
18587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
18597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1861f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1862f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1863f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1864f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1865f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1866f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1867f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1868f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1869f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1870f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1871f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1872f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1873ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1874ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1875584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1876584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1877584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1878584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1879584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1880a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1882a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1883a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1884a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
18856029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1886862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1887862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1888862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1889862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
18907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
18917636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
18937636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
18947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
18957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1896460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1897460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1898460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1899460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1900460a90540b045c102012da2492999557e6840526Jim Grosbach
1901460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1902460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1903460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1904460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1905460a90540b045c102012da2492999557e6840526Jim Grosbach
1906460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1907460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1908460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1909460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1910460a90540b045c102012da2492999557e6840526Jim Grosbach
19110e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
19120e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19130e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19140e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
19150e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
19170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
19180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1919ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1920ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1921ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1922ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1923ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1924ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1925ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1926ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1927ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1928ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1929ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1930ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
19316248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
19326248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19336248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
19366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
19376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
19386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
19396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
19406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
19416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
19426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
19456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
19466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
19506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
19556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
19569b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19579b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
19589b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach
19599b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
19609b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
19619b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19629b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19639b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    unsigned Value = ~CE->getValue();
19649b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19659b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19669b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19679b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19689b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffffff)
19699b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 24) | 0x600;
19706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1973f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1974f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1975f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1976f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1977f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1978f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1979f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1980f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1981f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1982f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1983f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1984f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1985b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1986b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
198789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
198821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
198989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
199089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
199189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
199289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
199389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
199489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
19953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
199621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1997345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1998345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1999345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
20003a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2001345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
2002345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2003fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
200421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
2005fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2006fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2007fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2008fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2009fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2010fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2011fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
201221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
2013fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
2014fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
2015fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
2016fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
2017fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
2018fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
20199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
20209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
20219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
20229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
20239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
20249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
20259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
20269b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2027d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
202821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
2029d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
2030d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
2031d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
2032d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
2033d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
2034d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
20353a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
203621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
2037762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
2038762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
2039762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2040762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
20413a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2042a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2043a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
204450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
204521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
2046762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
2047762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2048762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
20493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2050a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2051a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2052e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
2053e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
2054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
2055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
2056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
205721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
2058af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
2059af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
2060af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
2061af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
2062e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
2063e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
2064e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
2065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
206792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
206892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
206992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
207092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
207121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
2072af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
2073af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
2074af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
207592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
207692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
207792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
207892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
207992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
2080580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
20810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
208221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
2083580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
2084580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
20850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
20860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
20870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
20880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
20890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
20907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
209121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
20927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
20937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
20947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
20957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
20967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2098293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
2099293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
210021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
2101293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
2102293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
2103293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
2104293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
2105293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
2106293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2107293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
21087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
21095fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
2110cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
211121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
21120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
2113d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
211421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
2115d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2116275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
211721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
21180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
21190f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
21205fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
21217729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
212224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
2123cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
2124cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
2125cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
21268d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
21278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
21288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
2129862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
21300aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
2131862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
2132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
2133862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
21340aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2135862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
2136862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
2137862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
2138862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2139862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
214098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
21413471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                              bool isDoubleSpaced,
214298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
214398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
214498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
214598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
21463471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
214798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
214898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
214998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
215098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
215198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
21527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
215395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             unsigned Index,
215495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             bool isDoubleSpaced,
215595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             SMLoc S, SMLoc E) {
21567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
21577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
21587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
21597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
216095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
21617636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
21627636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
21637636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
21647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
21657636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
2166460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
2167460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
2168460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
2169460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
2170460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
2171460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
2172460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
2173460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2174460a90540b045c102012da2492999557e6840526Jim Grosbach
21753a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
217621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
2177762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
2178762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2179762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21803a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2181cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2182cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
21837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
21847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
21857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
21867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
21870d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
218857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
21897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
21903a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
219121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2192e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2193e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2194e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2195e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2196e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
219757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2198e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
21997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
22007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
22017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
22027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
220316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2204f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2205f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2206f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
22077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
220821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
22097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2210f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2211f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2212f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2213762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2214762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
22153a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2217706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2218706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
221921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2220706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2221706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2222706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2223706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2224706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
222721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2229a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2230a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2231a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2232a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2234584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
223521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2245b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2246fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
224721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
22486a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2249fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
225021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2251d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2252d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
225321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
22541a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    static const char *MaskStr[] = {
22551a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
22561a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
22571a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
225889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
225989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
226089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
226189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
226221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
226521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2266fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2267fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
22689b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
22699b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
22709b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
227121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
227421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2275fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2276fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
227721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2278706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2279706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
228021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
22816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2282e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
22836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2284fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
228521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2286f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2287f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2288f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2289f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2290f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2291f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
22927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
229321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2295a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2296a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2297a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2298a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2299a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
230221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
230350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2304fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
230521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2306580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2307580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2308e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
230921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
231092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2311efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2312efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2313efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
23140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
231521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
231692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2317efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2318efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2319efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
232092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
232121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
23227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
23237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
232421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2325293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2326293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2327293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
232821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
232921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
233021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
23318d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
23328d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
23335fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
23345fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
23357729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
23367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
23377729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
23388d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
23398d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
23408d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
23418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
23428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2343862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2344862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2345862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2346862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
234798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
234898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
234998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
235098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
23517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
23527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
23537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
23547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
235521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2356fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2357fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2358460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2359460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2360460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2361fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2362fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
23633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
23653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
23663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
23683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23693483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
23703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
237169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
237269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2373a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
23741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2375a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2376bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2377bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2378bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2379bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
23809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2381e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2382e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
23833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
23841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
238518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
23867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2387d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2388590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
23890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
23900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
23910c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
23920c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
23930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
23940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
23950c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
239640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
239740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
239840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
239940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
240040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
240140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
240240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
240340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
240440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
240540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
240640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
240740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
240840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
240940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
241040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
241140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
24120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
24130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2414a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2415aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // Check for aliases registered via .req. Canonicalize to lower case.
2416aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // That's more consistent since register names are case insensitive, and
2417aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // it's how the original entry was passed in from MC/MCParser/AsmParser.
2418aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
2419a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2420a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2421a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2422a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2423a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2424a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
242569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2426b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2427460a90540b045c102012da2492999557e6840526Jim Grosbach
2428e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2429e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2430d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
243119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
243219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
243319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
243419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
243519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
24360d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
24370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
24390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
24400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
24410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2442590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
24430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2444af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
24450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
24460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
24470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
24480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
24490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
24500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
24510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
24520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
245319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
24540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2455e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2457e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2458e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2459e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2460eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2461e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2463e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2464e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2465e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2466e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2467e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2468e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2469e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2470e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2471e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2472e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
24738a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
24748a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2475e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2476e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2477e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
247819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
247919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
248019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
248119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2482e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2483e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
248419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
248519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
248619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
248719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2488e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2489e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2490e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2491e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2492e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2493e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2494e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
249519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
249619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2497e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2498de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // shift by zero is a nop. Always send it through as lsl.
2499de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // ('as' compatibility)
2500de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      if (Imm == 0)
2501de626ad8726677328e10dbdc15011254214437d7Jim Grosbach        ShiftTy = ARM_AM::lsl;
2502e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
25031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2504e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
250519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
250619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
250719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
250819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
250919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
251019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2511e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
251219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
251319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2514e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2515e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
251692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
251792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2518af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
25190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
252092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
252192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
252292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
25230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
252419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
25250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
25260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
25270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
252850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
252950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
253050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2531e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2532e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2533e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
253450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
25351355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2536e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
25371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2538e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
253950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2540d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
254150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2543e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2544e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
254550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
254650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2547e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2548460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2549460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2550460a90540b045c102012da2492999557e6840526Jim Grosbach
2551460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2552460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2553460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2554460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2555460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2556460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2557460a90540b045c102012da2492999557e6840526Jim Grosbach
2558460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2559460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
256024dda217052b48373ed89d043a778aabb2f65080Jim Grosbach      return true;
2561460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2562ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (!MCE)
2563ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return TokError("immediate value expected for vector index");
2564460a90540b045c102012da2492999557e6840526Jim Grosbach
2565460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2566ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
2567ef4d3ebe2a36ebfd9370e1efbe74dff13f64c40fJim Grosbach      return Error(E, "']' expected");
2568460a90540b045c102012da2492999557e6840526Jim Grosbach
2569460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2570460a90540b045c102012da2492999557e6840526Jim Grosbach
2571460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2572460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2573460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
257499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
257599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
257650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2577a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2579fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2580fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2581fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2582fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2583e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2584e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2585e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
25864d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default: return -1;
2587e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2588fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2589e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2590e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2591e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2592e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2593e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2594e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2595e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2596e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2597e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2598e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2599e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2602e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2603e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2604fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2605e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2606e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2607e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2608e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2610e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2611e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2612e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2613e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2614e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2615e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2616e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2617e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
261889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
261989df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
262089df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
262189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
262289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
262389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
262489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
262589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
262689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
262789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
262889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
262989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
263089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
263189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
263289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
263389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
263489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
263589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
263689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
263789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
263889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
263989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
264089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
264189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
264289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
264389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
264489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
264589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
264689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
264789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
264889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
264989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
265089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
265189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
265289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
265343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2654fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2655fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2656f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
265743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2658e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2659e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2660c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2661c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2662e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2664e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2665f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2666e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2667e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2668fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2669f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2670fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2671fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
267243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2673fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2674fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2675f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
267643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2677fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2678fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2679c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2680c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2681fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2682fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2683fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2684f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2685fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2686fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2687fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2688f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2689e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2690e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
26919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
26929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
26939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
26949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
26969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
26989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
26999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
27009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
27019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
27039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
27049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
27059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
27069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
27099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
27109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
27119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
27139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
27149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
27169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
27179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
27189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
27199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
27209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
27219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
27229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
27239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
27249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2725d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2726d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2727d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2728d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2729d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2730d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2731d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2732d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2733d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2734d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2735bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid GPR number!");
2736d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2737d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2738d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2739d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2740d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2741d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2742d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2743d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2744d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2745d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2746d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2747ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2748ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2749ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2750ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2751ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2752ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2753ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2754ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2755ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2756ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2757ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2758ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2759ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
276025e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2761ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2762ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2763ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2764ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2765ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2766ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2767ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2768ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2769ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2770d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
277150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
27721355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
277318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2774a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2775e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2776d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2777d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
277816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2779d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2780d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2781d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2782d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2783d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2784d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2785ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2786ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2787ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2788ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2789ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2790ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2791ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2792ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2793ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2794ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
27951a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2796d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2797d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2798d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2799d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2800d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2801d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2802d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2803d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2804e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2805ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2806d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2807d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2808d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2811d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2812d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2813d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2814e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2815d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2816d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2817d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2818d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2819ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2820ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2821ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2822d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2823d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2824d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2825d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2826d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2827d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2828d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2829d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2830d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2831d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2832d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2833d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2834d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2835d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2836d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2837d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2838d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2839d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2840d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2841d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2842d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2843a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2844d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2845d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
28462d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2847ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2848ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2849ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2850ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2851ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2852ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2853d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2854d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2855d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2856d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2857be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach    if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg)) {
2858be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach      if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2859be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach        Warning(RegLoc, "register list not in ascending order");
2860be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach      else
2861be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach        return Error(RegLoc, "register list not in ascending order");
2862be7cf2b377d987f46d10f54f89ae4e1a71c37f55Jim Grosbach    }
2863a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) {
2864a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2865a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2866a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2867a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2868d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2869d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2870d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2871d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2872d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2873d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2874d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2875ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2876ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2877d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2878d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2879d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2880d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2881d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2882d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2883e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
288427debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
288550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
288627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
288727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
288827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
288927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
289027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
289127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
289227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
289350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2894d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2895d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
289698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
289798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
28987636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
28997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
290098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
290198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
290298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
290398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
290498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
290598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
290698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
290798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2908c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCExpr *LaneIndex;
2909c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    SMLoc Loc = Parser.getTok().getLoc();
2910c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (getParser().ParseExpression(LaneIndex)) {
2911c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "illegal expression");
2912c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
29137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
2914c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
2915c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (!CE) {
2916c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "lane index must be empty or an integer");
2917c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2918c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2919c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2920c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "']' expected");
2921c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2922c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2923c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Parser.Lex(); // Eat the ']'.
2924c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    int64_t Val = CE->getValue();
2925c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach
2926c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    // FIXME: Make this range check context sensitive for .8, .16, .32.
2927c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Val < 0 || Val > 7) {
2928c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "lane index out of range");
2929c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2930c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2931c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Index = Val;
2932c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    LaneKind = IndexedLane;
2933c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    return MatchOperand_Success;
293498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
293598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
293698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
293798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
293898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
2939862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2940862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2941862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
294298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
29437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
29445c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
29455c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
29465c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
29475c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
29485c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
29495c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
29505c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
29515c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
29525c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
29535c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
29547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
295598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
295698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
295798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
295898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
295998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29600aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
296198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
296298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
296398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29643471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
29653471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
296698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
296995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
297095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
297298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
29735c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
29745c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
29755c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
29765c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
29777636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
297898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
297998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
298098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
298198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
298298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
298328f08c93e75d291695ea89b9004145103292e85bJim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
2984c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
29850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
298698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
298798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
298898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
2989c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach        Reg = MRI->getMatchingSuperReg(Reg, ARM::dsub_0,
2990c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach                                   &ARMMCRegisterClasses[ARM::DPairRegClassID]);
29913471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
29923471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
299398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
299695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
299795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
299998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
30005c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
30015c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
30025c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
30035c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
30045c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
30055c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
30065c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
3007862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
3008862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3009862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
3010862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
3011862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3012862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
3013862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
3014862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
3015862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3016862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3017862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
3018276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
3019c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
3020c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
3021c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
3022c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
3023c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
30240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
30250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
3026c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
3027c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
3028c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
30297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
303098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
3031c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
3032e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
3033e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
3034e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
30350aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30360aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
30370aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
30380aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
30390aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
30400aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
30410aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3042e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
3043e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
3044e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
3045e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
3046e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
3047e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3048e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3049e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
3050e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
3051e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
3052e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
3053e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
3054e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
3055e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
3056e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
3057e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
3058e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
3059e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3060e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
3061e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
3062e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
3063e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
3064e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
3065e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
306698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
306798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
30687636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
30697636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
307098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
30717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
307298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
307398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
307498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
307598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
3076e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
3077e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
3078e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
3079e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
3080e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
3081e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
3082862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
3083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
3084862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
3085862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
3086862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
3087862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
3088862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3089862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3090c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
3091862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
3092862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
3093c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
3094c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
3095c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
3096c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
30970aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30980aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
30990aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
31000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
31010aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
31020aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
31030aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3104c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
3105c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
3106c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
3107c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
3108c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
3109c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
3110c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
311198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
311298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
31137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
311498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
31157636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
311698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
31177636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
311898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
311998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
312098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
3121c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
3122c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
31230aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
31240aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
31250aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
31260aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
31270aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
31280aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
31290aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
31300aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
3131862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
3132862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3133862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3134862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
313598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
313698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
31377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
313898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
31397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
314098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
31417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
314298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
314398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
314498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
3145862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3146862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3147862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3148862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
3149862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
3150862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3151862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3152862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
3153862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
315498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
315598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
3156c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // Two-register operands have been converted to the
3157c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    // composite register classes.
3158c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (Count == 2) {
3159c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      const MCRegisterClass *RC = (Spacing == 1) ?
3160c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
3161c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3162c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3163c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    }
316428f08c93e75d291695ea89b9004145103292e85bJim Grosbach
31650aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
31660aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
316798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
316898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
3169c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // Two-register operands have been converted to the
3170c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    // composite register classes.
31714d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    if (Count == 2) {
31724d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach      const MCRegisterClass *RC = (Spacing == 1) ?
31734d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach        &ARMMCRegisterClasses[ARM::DPairRegClassID] :
31744d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach        &ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
3175c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
3176c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    }
317798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
31783471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                            (Spacing == 2),
317998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
318098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
31817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
31827636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
318395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           LaneIndex,
318495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           (Spacing == 2),
318595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           S, E));
31867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
318798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
3188862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
3189862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
3190862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
319143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
3192f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
319343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3194706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3195706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3196706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3197706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
3198706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3199706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
3200706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
3201706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
3202032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
3203706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
3204032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
3205706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
3206706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
3207032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
3208706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
3209032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
3210706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
3211706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
3212706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
3213706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3214706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
3215f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
3216706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3217706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3218706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3219f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3220706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3221706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
322243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3223a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
322443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3227a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3229a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
32302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
32312dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3232a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
32332dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
32342dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
32352dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
32362dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
32372dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
32382dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
32392dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
32402dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
32412dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
32422dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
32432dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
32442dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
32452dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
32462dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
32472dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3248a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3249a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3250a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3251a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3252a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3254584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
325543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3256584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
325743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3258584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3259584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3260584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3261584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3262584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3263acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3264acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3265b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    std::string Name = Mask.lower();
3266b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    unsigned FlagsVal = StringSwitch<unsigned>(Name)
3267acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
3268acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
3269acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
3270acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
3271acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
3272acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
3273acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
3274acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
3275acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
3276acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
3277acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
3278acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
3279acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
3280acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
3281acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
328218c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3283acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3284acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3285acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3286acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
3287acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3288acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
328918c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3290acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3291acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3292acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3293acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3294acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3298590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3309b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
33144b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3318bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
33194b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
332156926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
332256926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3331584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3332584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3333584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3334584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
33407784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
33417784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
33427784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
33437784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
33447784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
33457784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
33467784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3347584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3349584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3350584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3351584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3352584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3355a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3356a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3357f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3358f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3359f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3360f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3361f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3362f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3366590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3367590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3372f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3373f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3374f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
33758a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33768a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3377f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3378f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3379f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3380f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3381f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3382f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3383f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3384f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3385f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3386f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3387f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3388f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3389f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3390f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3391f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3392f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3393f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3394f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3395f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3396f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3397f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3398f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3399f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3400f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3401f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3402f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3403f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3404c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3405c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3406c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3407c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3408c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3409c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3410c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3411c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3412c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3413c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3414c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3415c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3416c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3417c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3418c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3419c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3420c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3421c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3422c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3423c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3424c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3425c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3426c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3427c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3428580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3429580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3430580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3431580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3432580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3434580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3440580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3441580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3442580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3444580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3445580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3446580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3447580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3448580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3449580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3450580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3451580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3453580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
34548a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
34558a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3457580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3459580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3461580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3462580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3464580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3466580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3467580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3468580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3469580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3470580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3471580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3472580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3473580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3474580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3475580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3476580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3477580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3478580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3479580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
34800afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
34810afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
34820afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
34830afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
34840afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3485580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3486580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3487580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3488580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3489580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3490580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3491580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3492580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3493580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3494580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3495580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3496580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3497580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3498580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3499580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
35007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
35017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
35027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
35037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
35047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
35057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
35067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3507326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3508326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
35097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3510326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3511326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
35127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
35137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
35158a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35168a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
35177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
35187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
35217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
35237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
35247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
35257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
35267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
35297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
35307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
35317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
35357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
35367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
35377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
35387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
35397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
35407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
35417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
35427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
35447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
35457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
35467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
35477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
35487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3549293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3550293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3551293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3552293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
35538a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35548a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3555293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3556293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3557293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3558293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3559293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3560293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3561293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3562293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3563293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3565293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3567293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3568293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3569293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3570293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3571293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3572293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3573293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3574293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3575293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3576293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3577293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3578293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3580293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3581293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3582293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3583293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3584293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3585293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
35868a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35878a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3588293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3589293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3590293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3591293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3592293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3593293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3594293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3595293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3596293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3597293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3598293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3599293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3600293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3601293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3602293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3603293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3604293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3605293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3606293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3607293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3608293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3609293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3610293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3611293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3612293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3613293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3614293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3615293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3616293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
36177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
36187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3620f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3621f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3622f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
36237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
36247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
36257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
36267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
36287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
36297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
363016578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
36317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
36327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
36337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
36347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
36357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
36367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
363716578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
36387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
36397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
36407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
36417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
36427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
36437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
36447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
36457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
36467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
36477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
36487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
36497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3650f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3651f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
36520d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
36530d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
36540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
36550d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
36560d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3657f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3658f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3659f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
36607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
36617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
36627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
36637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3667251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3668251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3670251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3671251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3672251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3673251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3674251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3675251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3678251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3680251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
36818a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
36828a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3683251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3684251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3685251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3686251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3687251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3688251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3689251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3690251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3691251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3692251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3693251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3694251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3695251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3696251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3699251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3700251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3701251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3702251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3703251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3704251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3705251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3706251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3707251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3708251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3709251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3710251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3711251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3712251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3713251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3714251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3715251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3716251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3717251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3718251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3719251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3720251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3721251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3722251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3723251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3724251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3725251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3726251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3727251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3728251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3729251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3730251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3731251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3732251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3733251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3734251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3737a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3738a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3739a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3740a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3741a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3742a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3743a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3744a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3745a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3746a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3747a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3748a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3749a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3750a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3751a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3752a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3753a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3754a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3755a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3756a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3757a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3758a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3759a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3760a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3761a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3762a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3763a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3764a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3765a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3766a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3767a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3768a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3769a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3770a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3771eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3772eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3773eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3774eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3775eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3776eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3777eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3778eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3779eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3780eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3781eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3782eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3783eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3784eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3785eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3786eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3787ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3788ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3789ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3790ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3791ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3792ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3793ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3794ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3795ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3796ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3797ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3798ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3799ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3800ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
38011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3802ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3803ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3804ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
38051355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3806ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3807ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3808ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3809ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3810ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3811ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3813ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3814ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3815ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3816ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38179ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
38189ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38199ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
38209ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
38219ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
38229ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38239ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38249ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38259ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
38269ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
38279ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38289ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
38299ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38309ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
38319ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
38329ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
38339ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3834548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3835548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3836548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3837548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3838548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3839548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3840548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3841548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3842548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3843548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3844548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3845548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3846548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3847548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
38481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3849ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3850ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3851ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
38521355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3853ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3854ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3855ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3856548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3857548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3858548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
38607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
38617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
38627b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
38637b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38647b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
38657b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
38667b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
38677b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38687b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
38697b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38707b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38717b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
38727b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38737b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
38747b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
38757b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
38767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
38777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
38797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
38807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
38817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3883ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
38857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
38907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3891ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3892ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3893ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3894ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3896ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3897ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3898ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
38997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
39007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3902aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3903ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3904ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
39057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
39067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
39077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
39087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
39097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
39107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
39127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3913aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
39147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
39157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
39177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
39187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
39197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
39217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
39227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
39237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
39257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
39267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
39277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
39287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3932ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
39337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3934ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3935ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3936ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
39377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
39387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3939ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3940ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
39417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3942ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
39447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
39457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
39467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
39477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3948ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3949ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3950ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3951ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
39522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
39532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
39542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
39552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
39562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
39572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
39592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
39602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
39612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
39622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
39632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
39642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
39652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
39662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
39682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
39692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
397014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
397114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
397214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
397314605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
397414605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
397514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
397614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
397714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
397814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
397914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
398014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
398114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
398214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
398314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
398414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
398514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
398614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
398714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3988623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3989623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3990623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3991623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3992623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3993623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3994623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3995623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3996623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3997623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3998623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3999623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
4000623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
4001623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
400288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
400388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
400488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
400588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
400688ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
400788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
400888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
400988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
401088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
40117a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
40127a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
40137a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
40147a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
401588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
40167a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
401788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
401888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
401988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
402088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
40211b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
40221b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
40231b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
40241b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
40251b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
40261b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
40271b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
40281b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
40291b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
403088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
403188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
403288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
403388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
4034623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
403512431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
403612431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
403712431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
403812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
40396029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
404012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
404112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
404212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
404312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
404412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
404512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
404612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
404712431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
404812431329d617064d6e72dd040a58c1635cc261abJim Grosbach
404912431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
405012431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
405112431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
405212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
40536029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
405412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
405512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
405612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
405712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
405812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
405912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
406012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
406112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
406212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
406312431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
406412431329d617064d6e72dd040a58c1635cc261abJim Grosbach
40654334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
40664334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
40674334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40684334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
40694334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40704334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40714334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40724334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40736029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40744334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40754334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40764334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40774334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40784334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
40794334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
40804334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
40814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40824334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
40834334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
40874334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
40884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40896029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40924334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4095e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
40969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
409750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
40987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4099762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
410018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4101a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
4102762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
4103b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
4104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
410518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
41061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
41077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
41087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
4109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41100571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
41110571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
41120571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
41137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
41140571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
41157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
4116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
4117b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
4118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
412057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
412103f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
4122fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
4123fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
4124fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
4125fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4126fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
4127fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
4128fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
41297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
41307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
413150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
41327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
41337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
413450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
413557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
413657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
413757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
413857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
413957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
414057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
414157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
414257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
414357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
414457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
414557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
414657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
414757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
414857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
414957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
415057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
415157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
415257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
415357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
4154eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
4155eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4156eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
4157eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
415857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
415957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
416057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
416157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
416257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
416357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
416457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
416557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
416657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
416757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
416857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
416957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
417057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
417157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
417257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
417357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
417457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
417557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
417657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
417757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
417857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
417957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
418057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
418157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
418257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
418357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
418457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
418557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
41866cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
41876cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
41886cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
41898a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
41906cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
41918a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
41926cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
41937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
419450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
41950da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
41967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
41977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
41987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
419905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
42007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
42017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
42027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
42037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
42047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
42057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
42067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42070da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
42080da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
42090da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
42100da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
42110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
42127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
42137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
42147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
42157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
42167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
421705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
42187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
42197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
42207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
422157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
422257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4223a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
42257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
42267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
42277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
42287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4229762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
42307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
42329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4233d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
42347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
42357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
42367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
42377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
42387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
42397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
42407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
42417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
42427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
42439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
42457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
42467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
42477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
42487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
42507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
42510d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
42527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
42537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
42540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
42557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
42569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
425716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
42587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
42597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
42607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
42617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
42627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
42637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
42647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
426557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
42667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
42677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4268f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4269f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4270f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4271f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4272f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4273f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
42749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
42769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
42779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4280a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
42817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
42827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
42837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
42847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
428518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4287a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
428838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4289af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4290af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
42910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
42930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
42950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
42970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
42990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
43017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4302b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
43057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
43067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
43077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
43087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
43097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
43108a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
43118a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
43127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
43137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
43149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
43157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
43167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
43177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
43187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
43197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
43207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
43217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
43227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
43237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
43247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
43257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
43267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
43277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
43287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
43297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
43307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
43359d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
43369d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
43379d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
433851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Anything that can accept a floating point constant as an operand
433951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // needs to go through here, as the regular ParseExpression is
434051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // integer only.
434151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  //
434251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // This routine still creates a generic Immediate operand, containing
434351222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // a bitcast of the 64-bit floating point value. The various operands
434451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // that accept floats can check whether the value is valid for them
434551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // via the standard is*() predicates.
434651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
43479d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
43489d39036f62674606565217a10db28171b9594bc7Jim Grosbach
43498a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
43508a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
43519d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
43520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
43530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
43540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
43550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
43560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
43570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
43580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
43590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
43600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
43610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
43620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
43630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
43640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
43650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
43660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
43670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
43689d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
43699d39036f62674606565217a10db28171b9594bc7Jim Grosbach
43709d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
43719d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
43729d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
43739d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
43749d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
43759d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
43769d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
4377ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  SMLoc Loc = Tok.getLoc();
43789d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
437951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
43809d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
43819d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
438251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    IntVal ^= (uint64_t)isNegative << 31;
43839d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
438451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
438551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          MCConstantExpr::Create(IntVal, getContext()),
438651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          S, Parser.getTok().getLoc()));
43879d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43889d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
438951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Also handle plain integers. Instructions which allow floating point
439051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // immediates also allow a raw encoded 8-bit value.
43919d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
43929d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
43939d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
43949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
4395ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach      Error(Loc, "encoded floating point value out of range");
43969d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
43979d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
439851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    double RealVal = ARM_AM::getFPImmFloat(Val);
439951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
440051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
440151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        MCConstantExpr::Create(Val, getContext()), S,
440251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        Parser.getTok().getLoc()));
44039d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
44049d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
44059d39036f62674606565217a10db28171b9594bc7Jim Grosbach
4406ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  Error(Loc, "invalid floating point immediate");
44079d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
44089d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
440951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
44109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
44119c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
44121355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4413fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4414762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4415fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4416fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4417fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4418f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4419f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4420fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4421f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4422f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4423f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4424f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4425f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4426fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4427a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4428146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4429146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
443050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
443119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
44321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
443350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
44340d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
443519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
44360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
443719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
443819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
44393cbe43fe69680df772d83947ced97ca445861213Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
4440b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach    if (Mnemonic == "vmrs" &&
4441b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach        Parser.getTok().getString().equals_lower("apsr_nzcv")) {
44425cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
44435cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
4444b84ad4aa7dacfba5337520740d47770f2200201cJim Grosbach      Operands.push_back(ARMOperand::CreateToken("APSR_nzcv", S));
44455cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
44465cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4447e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4448e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4449e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
445019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4451758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
445267b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
44536284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
445467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4455515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4456515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4457515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4459515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
446050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4461762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
446250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
446350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
446450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4465a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
44661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4467d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
44681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
44698a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
447063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4471079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4472079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
4473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4474b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
447563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
4476515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
4477515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
447850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
447963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4480ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach    if (CE) {
4481ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      int32_t Val = CE->getValue();
4482ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      if (isNegative && Val == 0)
4483ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach        ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
448463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4485762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
448650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
448750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
448863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
44899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
44909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
44917597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
44927597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
44937597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
44941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
44959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44977597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
44987597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
44999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
45009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45017597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
45027597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
45039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
45047597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
45059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
45069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4508a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4509a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
45101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
45117597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
45121355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
45137597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
45149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
45168a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
45179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
45189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
45209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
45219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
45259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
45267597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
45279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
45287597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
45299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
45309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
45319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
45349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
45359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
45369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
45379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
45389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
45399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
45409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
45419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
45429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4543352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4544352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4545352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4546badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
454789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
45481355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
45495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
45505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
455189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
455289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4553352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4554352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4555a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4556352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4557badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4558352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4559352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
45605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
45615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
45625f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
45635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
45645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
45655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
45665f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
45676849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
45686849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "fmuls")
4569352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4570badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
45713f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
45723f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4573ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
457471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
457504d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
45762f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
45773f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
45783f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
45793f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
45803f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
45813f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
45823f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
45833f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
45843f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
45853f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
45863f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
45873f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
45883f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
45893f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
45903f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
45913f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
45923f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
45933f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
45943f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
45953f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
45963f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
45973f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
45983f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
45993f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
460052925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4601345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4602352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4603352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4604352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
460500f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
46065f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
46075f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
46085f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
460967ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
461048171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
46119c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach        Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
46126357caec785268d1e39059d03eb2034dee65467fJim Grosbach        Mnemonic == "fmuls" || Mnemonic == "fcmps" || Mnemonic == "fcmpzs" ||
4613e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4614352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4615352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4616352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4617352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4618a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4619a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4620a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4621a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4622a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4623a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4624a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4625a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4626a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4627a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4628a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4629a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4630a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4631a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4632a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
463389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
463489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
463589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
463689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
463789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
463889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4639352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4640352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
46413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
46423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
46433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
46443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
46453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4646fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
46471355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4648fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4649eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4650eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
46513443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4652eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4653d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4654eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4655d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
46563443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4657d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4658d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4659eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4660fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4661eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
46623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4663eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4664eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4665eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4666eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4667ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4668ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
46690780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
46702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
46712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
46722bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
46734af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
46744af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
46751ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
46763771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4677fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
46783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4679fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4680fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4681fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
468263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4683fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4684fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4685badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4686badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4687d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4688d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
468920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
469020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4691d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4692d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4693d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4694d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4695d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4696d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4697d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4698d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4699d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
47008adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4701d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4702d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4703d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4704d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
47053912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
47063912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
47073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
47083912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
47093912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
47103912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
47113912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
47123912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
471372f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
471420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
471520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
471620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4717f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4718f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4719f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
472072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
472172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
472272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
472320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
472420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
472520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
472672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4727f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4728f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
472920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
473020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
473120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4732f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4733f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
473420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
473520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
473620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
473720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
473820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
473920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
474020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
474112a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // check against T3. If the second register is the PC, this is an
474212a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // alternate form of ADR, which uses encoding T4, so check for that too.
474320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
474420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
474512a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC &&
474620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
474720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
474820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
474920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
475020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
475164944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
475220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
475320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
475420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
475520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
475620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
475720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
475820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
475920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
476020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
476164944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
476264944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
476364944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
476464944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
476564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
476664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
476764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
476864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
476964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
477064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
477164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
477264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
477364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
477464944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47751de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
477664944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
477764944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
477864944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
477964944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
478064944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
478164944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
478264944f48a1164c02c15ca423a53919682a89074cJim Grosbach
47837f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
47847f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
47857f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
47867f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
47877f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
47887f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
47897f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
47907f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
47917f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
47927f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
47937f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47947f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
47957f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
47967f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
479764944f48a1164c02c15ca423a53919682a89074cJim Grosbach
479820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4799f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4800f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4801f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4802f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4803f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4804f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4805f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
480672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
480772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
480872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
480972f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
48103912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4811d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4812d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4813d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
48147aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
48157aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
48167aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
48177aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
48187aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
48197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
48207aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
48217aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
48227aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
48237aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
48247aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
48257aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
48267aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
48277aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
48287aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
48297aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
483021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4831badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4832badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4833badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
483421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
483521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
483621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
483721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
483821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
483921d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
484021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
484121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4842a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4843a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4844a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4845a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4846a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4847a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4848a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4849a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4850a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4851badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4852badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4853ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4854badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4855352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4856352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4858352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
485989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
48601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
486189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4862badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
48630c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
48640c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
48650c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
48660c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
48670c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
48680c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4869ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4870ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
487189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
487289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
487389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
487489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
487589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
487689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4877f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4878f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4879f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4880f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4881f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
488289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
488389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
488489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
488589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
488689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4887f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
488889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
488989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
489089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
489189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
489289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4893f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
489489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
489589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4896ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4897ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
48989717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
48993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
49003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
49013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
49023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
49033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
49043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
49053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
49063771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
49071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
49083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
490933c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
491033c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
491133c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
491233c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4913ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
491433c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
491533c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4916c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4917c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4918c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4919c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4920c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4921c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4922c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
492333c16a27370939de39679245c3dff72383c210bdJim Grosbach
49243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4925f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4926f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
49273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4928f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4929f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
49303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
49313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
49323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4933f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4934f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
49353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4936f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4937badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4938345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4939a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4940a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4941a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4942a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4944a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4945a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4946345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
49475747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
49485747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
49495747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4950a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4951a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
49527aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
49537aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
49547aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
49557aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
49567aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
49577aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
495881d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
495981d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
496081d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
496181d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
49625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
49635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
49645747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
49655747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4966a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
49671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4968cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4969cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4970cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4971a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4972a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4973b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4974a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4975a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
49761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4977cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4978cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4979cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4980a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4981a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
498216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4983cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4984186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4985cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4986186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4987cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4988146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
498934e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4990ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4991d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4992d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4993d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
499420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
499520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
499620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
499720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
499820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4999ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5000ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
5001ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
5002ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
5003ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
5004cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
5005cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
5006cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
500721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
500821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
5009cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
5010cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
5011cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
5012cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
5013cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
5014cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
5015857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
5016857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
5017857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
5018857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
5019857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
5020857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
5021857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5022857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5023857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
5024857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
5025857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
5026857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
502768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
502868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
502968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
503068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
503168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
503268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
503368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
503468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
503568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
503668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
503768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5038857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
5039857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
5040857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
5041934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
504255b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
504355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
5044934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
504555b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
504655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
5047934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
5048934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
5049934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
505055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
505155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
5052d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
5053d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
5054d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
505555b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
5056d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
5057934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
5058934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
5059934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
5060934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
5061934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
5062934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
50639898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
5064ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5065ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5066189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
5067aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
5068aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
5069aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
5070aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
5071aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
5072aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
5073aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
5074aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
5075aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
5076aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
5077aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
5078aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
5079aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
5080aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
5081aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
5082aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
5083aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
5084aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
508576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
508676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
508776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
508876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
508976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
509076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
509176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
509276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
509376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
509476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
509576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
5096f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
5097f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
5098f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
5099f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
51001a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5101f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
51021a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
5103f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
5104f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
5105f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5106189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
5107189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
5108189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
5109189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
51101a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
5111f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
5112f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
511374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // NOTE: BKPT instruction has the interesting property of being
511474423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  // allowed in IT blocks, but not being predicable.  It just always
5115b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
511674423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT &&
511774423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      Inst.getOpcode() != ARM::BKPT) {
5118f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
5119f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
5120f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
5121f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
5122a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
5123f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
5124f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
5125f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
5126f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
5127f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
5128f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
5129f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
5130f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
5131f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
5132f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
5133f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
5134f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
5135f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
5136f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
5137f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
5138f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
5139f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
5140c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
5141f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
5142f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
514351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
514451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
5145f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
5146f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5147189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
51482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
51492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
51502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
5151189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
5152189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5153189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
5154189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5155189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
5156189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5157189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
5158189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5159189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
516014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
516114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
516214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
516314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
516414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
516514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
516614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
516714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
516814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
516953642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
517053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
5171189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
5172189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5173189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5174189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
5175189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
517614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5177189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
5178189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5179189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5180fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
5181fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
5182fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
5183fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
5184fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
5185fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
5186fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
5187fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
518800c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
5189fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
519093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
519176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
519276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
519376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
519476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
519576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
519693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
519793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
519893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
51997260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
52007260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
52017260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
5202aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
520376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
5204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
5205aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
520693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
520776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
520893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
520993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
521076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
521176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
5212aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
52137260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
52147260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
52157260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
521693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
521793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
521893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
521976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
522076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
522176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
522276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
522376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
522476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
522576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
52265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
52275402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
52285402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
52296dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5230aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
52315402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
52325402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5233aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5234aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
52356dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
52366dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
52376dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5238aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
52395402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
52405402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5241aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5242aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
52436dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
52446dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
52451e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
52461e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
52478213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
52481e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
52491e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
52501e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
52511e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5252189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5253189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5254189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5255189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5256189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5257d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) {
525884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
5259bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
52609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
52617945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
52627945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
52637945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
52647945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST1LNd8_UPD;
52657945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD;
52667945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32: Spacing = 1; return ARM::VST1LNd32_UPD;
52677945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_8:  Spacing = 1; return ARM::VST1LNd8;
52687945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_16: Spacing = 1; return ARM::VST1LNd16;
52697945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST1LNdAsm_32: Spacing = 1; return ARM::VST1LNd32;
52709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
52727945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
52737945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
52747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
52757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
52767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
52777945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
52787945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST2LNd8_UPD;
52797945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_16: Spacing = 1; return ARM::VST2LNd16_UPD;
52807945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32: Spacing = 1; return ARM::VST2LNd32_UPD;
52817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_16: Spacing = 2; return ARM::VST2LNq16_UPD;
52827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqWB_register_Asm_32: Spacing = 2; return ARM::VST2LNq32_UPD;
52837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach
52847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_8:  Spacing = 1; return ARM::VST2LNd8;
52857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_16: Spacing = 1; return ARM::VST2LNd16;
52867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNdAsm_32: Spacing = 1; return ARM::VST2LNd32;
52877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_16: Spacing = 2; return ARM::VST2LNq16;
52887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST2LNqAsm_32: Spacing = 2; return ARM::VST2LNq32;
5289d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
52904adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  // VST3LN
52917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
52927945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
52937945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
52947945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST3LNq16_UPD;
52957945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
52967945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST3LNd8_UPD;
52977945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16: Spacing = 1; return ARM::VST3LNd16_UPD;
52987945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32: Spacing = 1; return ARM::VST3LNd32_UPD;
52997945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16: Spacing = 2; return ARM::VST3LNq16_UPD;
53007945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: Spacing = 2; return ARM::VST3LNq32_UPD;
53017945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_8:  Spacing = 1; return ARM::VST3LNd8;
53027945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_16: Spacing = 1; return ARM::VST3LNd16;
53037945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNdAsm_32: Spacing = 1; return ARM::VST3LNd32;
53047945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_16: Spacing = 2; return ARM::VST3LNq16;
53057945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3LNqAsm_32: Spacing = 2; return ARM::VST3LNq32;
53064adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
5307d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3
53087945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
53097945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
53107945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
53117945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
53127945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
53137945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
53147945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_8:  Spacing = 1; return ARM::VST3d8_UPD;
53157945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_16: Spacing = 1; return ARM::VST3d16_UPD;
53167945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dWB_register_Asm_32: Spacing = 1; return ARM::VST3d32_UPD;
53177945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_8:  Spacing = 2; return ARM::VST3q8_UPD;
53187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_16: Spacing = 2; return ARM::VST3q16_UPD;
53197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qWB_register_Asm_32: Spacing = 2; return ARM::VST3q32_UPD;
53207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_8:  Spacing = 1; return ARM::VST3d8;
53217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_16: Spacing = 1; return ARM::VST3d16;
53227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3dAsm_32: Spacing = 1; return ARM::VST3d32;
53237945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_8:  Spacing = 2; return ARM::VST3q8;
53247945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_16: Spacing = 2; return ARM::VST3q16;
53257945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VST3qAsm_32: Spacing = 2; return ARM::VST3q32;
5326539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
532788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  // VST4LN
532888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
532988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
533088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
533188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VST4LNq16_UPD;
533288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
533388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VST4LNd8_UPD;
533488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16: Spacing = 1; return ARM::VST4LNd16_UPD;
533588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32: Spacing = 1; return ARM::VST4LNd32_UPD;
533688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16: Spacing = 2; return ARM::VST4LNq16_UPD;
533788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: Spacing = 2; return ARM::VST4LNq32_UPD;
533888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:  Spacing = 1; return ARM::VST4LNd8;
533988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16: Spacing = 1; return ARM::VST4LNd16;
534088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32: Spacing = 1; return ARM::VST4LNd32;
534188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16: Spacing = 2; return ARM::VST4LNq16;
534288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: Spacing = 2; return ARM::VST4LNq32;
534388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
5344539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4
5345539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5346539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5347539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5348539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5349539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5350539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5351539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:  Spacing = 1; return ARM::VST4d8_UPD;
5352539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16: Spacing = 1; return ARM::VST4d16_UPD;
5353539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32: Spacing = 1; return ARM::VST4d32_UPD;
5354539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:  Spacing = 2; return ARM::VST4q8_UPD;
5355539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16: Spacing = 2; return ARM::VST4q16_UPD;
5356539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: Spacing = 2; return ARM::VST4q32_UPD;
5357539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:  Spacing = 1; return ARM::VST4d8;
5358539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16: Spacing = 1; return ARM::VST4d16;
5359539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32: Spacing = 1; return ARM::VST4d32;
5360539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:  Spacing = 2; return ARM::VST4q8;
5361539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16: Spacing = 2; return ARM::VST4q16;
5362539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: Spacing = 2; return ARM::VST4q32;
536384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
536484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
536584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
5366d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbachstatic unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) {
53677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
5368bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("unexpected opcode!");
53699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
53707945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
53717945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
53727945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
53737945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD1LNd8_UPD;
53747945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD;
53757945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD1LNd32_UPD;
53767945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_8:  Spacing = 1; return ARM::VLD1LNd8;
53777945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_16: Spacing = 1; return ARM::VLD1LNd16;
53787945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD1LNdAsm_32: Spacing = 1; return ARM::VLD1LNd32;
53799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
53809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
53817945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
53827945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
53837945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
53847945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD2LNq16_UPD;
53857945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
53867945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD2LNd8_UPD;
53877945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD2LNd16_UPD;
53887945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD2LNd32_UPD;
53897945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD2LNq16_UPD;
53907945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD2LNq32_UPD;
53917945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_8:  Spacing = 1; return ARM::VLD2LNd8;
53927945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_16: Spacing = 1; return ARM::VLD2LNd16;
53937945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNdAsm_32: Spacing = 1; return ARM::VLD2LNd32;
53947945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_16: Spacing = 2; return ARM::VLD2LNq16;
53957945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD2LNqAsm_32: Spacing = 2; return ARM::VLD2LNq32;
53963a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
53975e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP
53985e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
53995e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
54005e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
54015e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD3DUPq8_UPD;
54025e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3DUPq16_UPD;
54035e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
54045e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3DUPd8_UPD;
54055e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD3DUPd16_UPD;
54065e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD3DUPd32_UPD;
54075e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD3DUPq8_UPD;
54085e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD3DUPq16_UPD;
54095e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD3DUPq32_UPD;
54105e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:  Spacing = 1; return ARM::VLD3DUPd8;
54115e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16: Spacing = 1; return ARM::VLD3DUPd16;
54125e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32: Spacing = 1; return ARM::VLD3DUPd32;
54135e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8: Spacing = 2; return ARM::VLD3DUPq8;
54145e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16: Spacing = 2; return ARM::VLD3DUPq16;
54155e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: Spacing = 2; return ARM::VLD3DUPq32;
54165e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
54173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  // VLD3LN
54187945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
54197945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
54207945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
54217945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3LNq16_UPD;
54227945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
54237945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD3LNd8_UPD;
54247945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD3LNd16_UPD;
54257945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD3LNd32_UPD;
54267945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD3LNq16_UPD;
54277945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD3LNq32_UPD;
54287945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_8:  Spacing = 1; return ARM::VLD3LNd8;
54297945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_16: Spacing = 1; return ARM::VLD3LNd16;
54307945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNdAsm_32: Spacing = 1; return ARM::VLD3LNd32;
54317945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_16: Spacing = 2; return ARM::VLD3LNq16;
54327945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3LNqAsm_32: Spacing = 2; return ARM::VLD3LNq32;
5433c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
5434c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3
54357945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
54367945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
54377945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
54387945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
54397945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
54407945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
54417945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:  Spacing = 1; return ARM::VLD3d8_UPD;
54427945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_16: Spacing = 1; return ARM::VLD3d16_UPD;
54437945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dWB_register_Asm_32: Spacing = 1; return ARM::VLD3d32_UPD;
54447945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:  Spacing = 2; return ARM::VLD3q8_UPD;
54457945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_16: Spacing = 2; return ARM::VLD3q16_UPD;
54467945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: Spacing = 2; return ARM::VLD3q32_UPD;
54477945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_8:  Spacing = 1; return ARM::VLD3d8;
54487945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_16: Spacing = 1; return ARM::VLD3d16;
54497945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3dAsm_32: Spacing = 1; return ARM::VLD3d32;
54507945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_8:  Spacing = 2; return ARM::VLD3q8;
54517945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_16: Spacing = 2; return ARM::VLD3q16;
54527945eade3d8db8c1dd52a291cee5d55ac0539586Jim Grosbach  case ARM::VLD3qAsm_32: Spacing = 2; return ARM::VLD3q32;
54538abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
5454e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  // VLD4LN
5455e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5456e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5457e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5458e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4LNq16_UPD;
5459e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5460e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4LNd8_UPD;
5461e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16: Spacing = 1; return ARM::VLD4LNd16_UPD;
5462e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32: Spacing = 1; return ARM::VLD4LNd32_UPD;
5463e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16: Spacing = 2; return ARM::VLD4LNq16_UPD;
5464e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: Spacing = 2; return ARM::VLD4LNq32_UPD;
5465e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:  Spacing = 1; return ARM::VLD4LNd8;
5466e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16: Spacing = 1; return ARM::VLD4LNd16;
5467e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32: Spacing = 1; return ARM::VLD4LNd32;
5468e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16: Spacing = 2; return ARM::VLD4LNq16;
5469e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: Spacing = 2; return ARM::VLD4LNq32;
5470e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
5471a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP
5472a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5473a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5474a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5475a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8: Spacing = 1; return ARM::VLD4DUPq8_UPD;
5476a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4DUPq16_UPD;
5477a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5478a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:  Spacing = 1; return ARM::VLD4DUPd8_UPD;
5479a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16: Spacing = 1; return ARM::VLD4DUPd16_UPD;
5480a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32: Spacing = 1; return ARM::VLD4DUPd32_UPD;
5481a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8: Spacing = 2; return ARM::VLD4DUPq8_UPD;
5482a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16: Spacing = 2; return ARM::VLD4DUPq16_UPD;
5483a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: Spacing = 2; return ARM::VLD4DUPq32_UPD;
5484a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:  Spacing = 1; return ARM::VLD4DUPd8;
5485a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16: Spacing = 1; return ARM::VLD4DUPd16;
5486a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32: Spacing = 1; return ARM::VLD4DUPd32;
5487a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8: Spacing = 2; return ARM::VLD4DUPq8;
5488a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16: Spacing = 2; return ARM::VLD4DUPq16;
5489a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: Spacing = 2; return ARM::VLD4DUPq32;
5490a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
54918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  // VLD4
54928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
54938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
54948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
54958abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
54968abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
54978abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
54988abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:  Spacing = 1; return ARM::VLD4d8_UPD;
54998abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16: Spacing = 1; return ARM::VLD4d16_UPD;
55008abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32: Spacing = 1; return ARM::VLD4d32_UPD;
55018abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:  Spacing = 2; return ARM::VLD4q8_UPD;
55028abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16: Spacing = 2; return ARM::VLD4q16_UPD;
55038abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: Spacing = 2; return ARM::VLD4q32_UPD;
55048abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:  Spacing = 1; return ARM::VLD4d8;
55058abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16: Spacing = 1; return ARM::VLD4d16;
55068abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32: Spacing = 1; return ARM::VLD4d32;
55078abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:  Spacing = 2; return ARM::VLD4q8;
55088abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16: Spacing = 2; return ARM::VLD4q16;
55098abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: Spacing = 2; return ARM::VLD4q32;
55107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
55117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
55127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
551383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5514f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5515f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5516f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
55170b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  // Aliases for alternate PC+imm syntax of LDR instructions.
55180b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRpcrel:
55190b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRpci);
55200b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55210b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRBpcrel:
55220b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRBpci);
55230b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55240b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRHpcrel:
55250b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRHpci);
55260b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55270b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSBpcrel:
55280b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSBpci);
55290b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55300b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSHpcrel:
55310b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSHpci);
55320b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
55339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
55348b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
55358b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
55368b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32: {
553784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
553884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
553984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
55405b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5541d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
554284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
554384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
554484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
554584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
554684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
554784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
554884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
554984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
555084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
555184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
555284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
55539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55548b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
55558b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
55568b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
55578b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
55588b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32: {
55599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
55609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
55625b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5563d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
55649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55695b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55705b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
55719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
55749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
55759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
55769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
55774adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
55784adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_8:
55794adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_16:
55804adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_register_Asm_32:
55814adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_16:
55824adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_register_Asm_32: {
55834adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
55844adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55854adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
55864adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
55874adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
55884adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55894adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55904adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55914adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55924adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55934adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55944adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
55954adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55964adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
55974adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55984adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55994adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
56004adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
56014adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
56024adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
56034adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
560488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_8:
560588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_16:
560688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_register_Asm_32:
560788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_16:
560888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_register_Asm_32: {
560988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
561088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
561188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
561288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
561388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
561488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
561588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
561688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
561788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
561888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
561988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
562088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
562188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
562288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
562388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
562488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
562588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
562688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
562788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
562888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
562988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
563088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
563188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
56328b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
56338b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
56348b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: {
563584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
563684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
563784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
56385b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5639d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
564084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
564184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
564284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
564384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
564484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
564584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
564684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
564784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
564884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
564984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
565084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
56519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56528b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
56538b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
56548b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
56558b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
56568b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: {
56579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
56589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
56605b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5661d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
56629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56675b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56685b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
56699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
56739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
56749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
56754adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
56764adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_8:
56774adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_16:
56784adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdWB_fixed_Asm_32:
56794adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_16:
56804adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqWB_fixed_Asm_32: {
56814adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
56824adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56834adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
56844adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
56854adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
56864adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56874adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56884adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56894adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56904adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56914adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56924adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
56934adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56944adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
56954adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56964adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56974adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56984adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
56994adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
57004adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
57014adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
570288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_8:
570388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_16:
570488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdWB_fixed_Asm_32:
570588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_16:
570688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqWB_fixed_Asm_32: {
570788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
570888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
570988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
571088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
571188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
571288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
571388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
571488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
571588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
571688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
571788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
571888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
571988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
572088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
572188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
572288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
572388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
572488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
572588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
572688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
572788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
572888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
572988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
57308b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
57318b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
57328b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32: {
573384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
573484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
573584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
57365b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5737d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
573884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
573984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
574084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
574184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
574284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
574384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
574484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
574584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
574684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
57479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
57488b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
57498b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
57508b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
57518b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
57528b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32: {
57539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
57549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
57565b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
5757d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57615b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57625b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
57639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
57679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
57689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
57694adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
57704adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_8:
57714adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_16:
57724adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNdAsm_32:
57734adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_16:
57744adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  case ARM::VST3LNqAsm_32: {
57754adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    MCInst TmpInst;
57764adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57774adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    // right place.
57784adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    unsigned Spacing;
57794adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
57804adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57814adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57824adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57834adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57844adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing));
57854adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57864adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach                                            Spacing * 2));
57874adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57884adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57894adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
579088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    Inst = TmpInst;
579188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    return true;
579288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  }
579388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach
579488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_8:
579588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_16:
579688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNdAsm_32:
579788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_16:
579888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach  case ARM::VST4LNqAsm_32: {
579988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    MCInst TmpInst;
580088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // Shuffle the operands around so the lane index operand is in the
580188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    // right place.
580288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    unsigned Spacing;
580388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
580488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
580588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
580688a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
580788a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
580888a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing));
580988a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
581088a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 2));
581188a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
581288a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach                                            Spacing * 3));
581388a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
581488a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
581588a54de799240d5de2e79dfff4671ad5653e7cebJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
58164adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    Inst = TmpInst;
58174adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach    return true;
58184adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach  }
58194adb18234278d6d40e5791e0dd6970be9a4b0b57Jim Grosbach
58209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
58218b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
58228b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
58238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: {
5824872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5825872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5826872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
582795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5828d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5829872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5830872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5831872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5832872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5833872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5834872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5835872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5836872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5837872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5838872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5839872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5840872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
58419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58428b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
58438b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
58448b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
58458b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
58468b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: {
58479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
58489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
58499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
585095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5851d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
58529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
585395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
585495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
58559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
58599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
586095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
586195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
58629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
58649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
58659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
58669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
58679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
58689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
58693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
58703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
58713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
58723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
58733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: {
58743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
58753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
58763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
58773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
5878d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
58793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
58803a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
58823a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5883c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
58843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
58853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
58863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
58873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
58883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
58893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
58903a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
58913a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5892c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
58933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
58943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
58953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
58963a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
58973a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
58983a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
58993a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
5900e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_8:
5901e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_16:
5902e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_register_Asm_32:
5903e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_16:
5904e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_register_Asm_32: {
5905e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
5906e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
5907e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
5908e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
5909e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5910e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5911e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5912e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5913e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5914e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5915e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5916e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5917e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5918e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5919e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5920e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5921e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5922e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5923e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
5924e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5925e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
5926e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5927e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
5928e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5929e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5930e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5931e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
5932e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
5933e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
5934e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
59358b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
59368b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
59378b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: {
5938872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5939872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5940872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
594195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5942d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
5943872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5944872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5945872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5946872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5947872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
5948872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5949872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5950872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
5951872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
5952872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5953872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5954872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
59559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59568b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
59578b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
59588b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
59598b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
59608b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: {
59619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
59629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
59639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
596495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
5965d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
596795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
596895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
59709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
59719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
59729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
59739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
597495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
597595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
59769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
59779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
59789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
59799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
59809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
59819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
59829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
59833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
59843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
59853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
59863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
59873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: {
59883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
59893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
59903a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
59913a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
5992d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
59933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
59943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
59953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
59963a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
5997c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
59983a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
59993a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60003a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60013a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
60023a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60033a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
60043a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
60053a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6006c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
60073a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60083a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60093a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60103a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
60113a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
60123a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
60133a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6014e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_8:
6015e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_16:
6016e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdWB_fixed_Asm_32:
6017e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_16:
6018e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqWB_fixed_Asm_32: {
6019e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6020e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6021e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6022e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6023e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6024e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6025e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6026e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6027e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6028e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6029e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6030e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6031e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
6032e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6033e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6034e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6035e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6036e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6037e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6038e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6039e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6040e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6041e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6042e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6043e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6044e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6045e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6046e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6047e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6048e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
60498b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
60508b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
60518b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32: {
60527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
60537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
60547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
605595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6056d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
60587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
60617636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60627636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60637636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
60657636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
60667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
60679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
60688b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
60698b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
60708b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
60718b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
60728b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32: {
60739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
60749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
60759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
607695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
6077d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
60789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
607995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
608095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
60829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
60839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
608495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
608595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
60869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
60879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
60889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
60899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
60909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
60919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
60923a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
60933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
60943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
60953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
60963a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
60973a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32: {
60983a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
60993a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
61003a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
61013a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
6102d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61033a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61043a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61053a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61063a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6107c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61083a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
61093a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
61103a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
61113a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61123a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
61133a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6114c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
61153a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
61163a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
61173a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
61183a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
61193a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
61203a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
61213a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
6122e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_8:
6123e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_16:
6124e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNdAsm_32:
6125e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_16:
6126e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  case ARM::VLD4LNqAsm_32: {
6127e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    MCInst TmpInst;
6128e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
6129e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    // right place.
6130e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    unsigned Spacing;
6131e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6132e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6133e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6134e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6135e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6136e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6137e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6138e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6139e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
6140e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
6141e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
6142e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6143e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing));
6144e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6145e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 2));
6146e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6147e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach                                            Spacing * 3));
6148e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
6149e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6150e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6151e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    Inst = TmpInst;
6152e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach    return true;
6153e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach  }
6154e983a134e7e40e214f590c3d8ba565bb85f39628Jim Grosbach
61555e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  // VLD3DUP single 3-element structure to all lanes instructions.
61565e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_8:
61575e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_16:
61585e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdAsm_32:
61595e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_8:
61605e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_16:
61615e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqAsm_32: {
61625e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61635e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61645e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61655e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61665e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61675e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61685e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61695e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61705e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61715e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61725e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
61735e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
61745e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61755e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
61765e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
61775e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
61785e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_8:
61795e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_16:
61805e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_fixed_Asm_32:
61815e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_8:
61825e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_16:
61835e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_fixed_Asm_32: {
61845e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
61855e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
61865e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
61875e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
61885e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61895e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
61905e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
61915e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
61925e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
61935e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
61945e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
61955e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
61965e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
61975e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
61985e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
61995e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
62005e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
62015e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
62025e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_8:
62035e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_16:
62045e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPdWB_register_Asm_32:
62055e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_8:
62065e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_16:
62075e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  case ARM::VLD3DUPqWB_register_Asm_32: {
62085e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    MCInst TmpInst;
62095e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    unsigned Spacing;
62105e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
62115e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
62125e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62135e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing));
62145e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
62155e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach                                            Spacing * 2));
62165e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
62175e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
62185e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
62195e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
62205e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
62215e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
62225e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    Inst = TmpInst;
62235e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach    return true;
62245e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach  }
62255e59f7e15ed3770b32481cd72d2c15b159e991e6Jim Grosbach
6226c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  // VLD3 multiple 3-element structure instructions.
6227c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_8:
6228c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_16:
6229c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dAsm_32:
6230c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_8:
6231c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_16:
6232c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qAsm_32: {
6233c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6234c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6235d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6236c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6237c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6238c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6239c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6240c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6241c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6242c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6243c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6244c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6245c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6246c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6247c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6248c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6249c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_8:
6250c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_16:
6251c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_fixed_Asm_32:
6252c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_8:
6253c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_16:
6254c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_fixed_Asm_32: {
6255c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6256c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6257d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6258c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6259c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6260c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6261c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6262c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6263c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6264c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6265c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6266c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6267c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6268c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6269c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6270c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6271c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6272c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6273c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_8:
6274c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_16:
6275c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3dWB_register_Asm_32:
6276c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_8:
6277c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_16:
6278c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  case ARM::VLD3qWB_register_Asm_32: {
6279c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    MCInst TmpInst;
6280c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    unsigned Spacing;
6281d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6282d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6283d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6284d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6285d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6286d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6287d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6288d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6289d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6290d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6291d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6292d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6293d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6294d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6295d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6296d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6297a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4DUP single 3-element structure to all lanes instructions.
6298a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_8:
6299a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_16:
6300a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdAsm_32:
6301a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_8:
6302a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_16:
6303a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqAsm_32: {
6304a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6305a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6306a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6307a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6308a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6309a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6310a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6311a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6312a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6313a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6314a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6315a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6316a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6317a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6318a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6319a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6320a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6321a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6322a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_8:
6323a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_16:
6324a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_fixed_Asm_32:
6325a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_8:
6326a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_16:
6327a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_fixed_Asm_32: {
6328a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6329a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6330a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6331a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6332a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6333a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6334a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6335a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6336a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6337a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6338a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6339a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6340a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6341a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6342a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6343a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6344a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6345a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6346a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6347a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6348a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_8:
6349a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_16:
6350a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPdWB_register_Asm_32:
6351a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_8:
6352a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_16:
6353a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  case ARM::VLD4DUPqWB_register_Asm_32: {
6354a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    MCInst TmpInst;
6355a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    unsigned Spacing;
6356a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
6357a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6358a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6359a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing));
6360a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6361a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 2));
6362a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6363a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach                                            Spacing * 3));
6364a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6365a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6366a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6367a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6368a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6369a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6370a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    Inst = TmpInst;
6371a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach    return true;
6372a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  }
6373a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach
6374a57a36abe7d0b769a495ed886246db157aff4addJim Grosbach  // VLD4 multiple 4-element structure instructions.
63758abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_8:
63768abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_16:
63778abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dAsm_32:
63788abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_8:
63798abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_16:
63808abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qAsm_32: {
63818abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
63828abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
63838abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
63848abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
63858abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63868abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
63878abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63888abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
63898abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
63908abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
63918abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
63928abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
63938abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
63948abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
63958abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
63968abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
63978abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
63988abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
63998abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_8:
64008abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_16:
64018abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_fixed_Asm_32:
64028abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_8:
64038abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_16:
64048abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_fixed_Asm_32: {
64058abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
64068abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
64078abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
64088abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
64098abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64108abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
64118abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64128abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
64138abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64148abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
64158abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
64168abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
64178abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
64188abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
64198abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
64208abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
64218abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
64228abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
64238abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
64248abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
64258abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_8:
64268abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_16:
64278abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4dWB_register_Asm_32:
64288abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_8:
64298abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_16:
64308abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  case ARM::VLD4qWB_register_Asm_32: {
64318abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    MCInst TmpInst;
64328abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    unsigned Spacing;
64338abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.setOpcode(getRealVLDOpcode(Inst.getOpcode(), Spacing));
64348abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
64358abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64368abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing));
64378abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64388abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 2));
64398abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
64408abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach                                            Spacing * 3));
64418abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
64428abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
64438abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
64448abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
64458abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
64468abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
64478abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    Inst = TmpInst;
64488abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach    return true;
64498abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach  }
64508abe7e33641fccfa70a7e335939e83dfbf654fe8Jim Grosbach
6451d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  // VST3 multiple 3-element structure instructions.
6452d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_8:
6453d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_16:
6454d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dAsm_32:
6455d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_8:
6456d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_16:
6457d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qAsm_32: {
6458d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6459d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6460d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6461d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6462d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6463d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6464d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6465d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6466d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6467d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6468d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6469d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6470d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6471d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6472d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6473d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6474d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_8:
6475d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_16:
6476d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_fixed_Asm_32:
6477d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_8:
6478d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_16:
6479d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_fixed_Asm_32: {
6480d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6481d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6482d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6483d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6484d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6485d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6486d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6487c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6488c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6489c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing));
6490c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6491c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach                                            Spacing * 2));
6492d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6493d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6494d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    Inst = TmpInst;
6495d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    return true;
6496d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  }
6497d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach
6498d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_8:
6499d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_16:
6500d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3dWB_register_Asm_32:
6501d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_8:
6502d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_16:
6503d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach  case ARM::VST3qWB_register_Asm_32: {
6504d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    MCInst TmpInst;
6505d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    unsigned Spacing;
6506d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6507c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6508c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6509c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6510c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6511d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6512d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6513d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing));
6514d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6515d7433e2873706265d545edc5cdd0a728dd71ef66Jim Grosbach                                            Spacing * 2));
6516c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6517c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6518c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    Inst = TmpInst;
6519c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach    return true;
6520c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach  }
6521c387fc66bd52e4276fdc2704a3aaed57cc1f9a11Jim Grosbach
6522539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  // VST4 multiple 3-element structure instructions.
6523539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_8:
6524539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_16:
6525539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dAsm_32:
6526539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_8:
6527539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_16:
6528539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qAsm_32: {
6529539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6530539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6531539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6532539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6533539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6534539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6535539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6536539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6537539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6538539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6539539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6540539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6541539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6542539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6543539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6544539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6545539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6546539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6547539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_8:
6548539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_16:
6549539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_fixed_Asm_32:
6550539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_8:
6551539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_16:
6552539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_fixed_Asm_32: {
6553539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6554539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6555539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6556539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6557539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6558539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6559539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
6560539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6561539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6562539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6563539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6564539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6565539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6566539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6567539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6568539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6569539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6570539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6571539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6572539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6573539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_8:
6574539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_16:
6575539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4dWB_register_Asm_32:
6576539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_8:
6577539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_16:
6578539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  case ARM::VST4qWB_register_Asm_32: {
6579539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    MCInst TmpInst;
6580539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    unsigned Spacing;
6581539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.setOpcode(getRealVSTOpcode(Inst.getOpcode(), Spacing));
6582539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6583539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn_wb == tied Rn
6584539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // alignment
6585539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // Rm
6586539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
6587539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6588539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing));
6589539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6590539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 2));
6591539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
6592539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach                                            Spacing * 3));
6593539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
6594539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
6595539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    Inst = TmpInst;
6596539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach    return true;
6597539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach  }
6598539aab771fea06bd230789e19c9672ef80ad1c7eJim Grosbach
6599863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
66002cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVsr:
66012cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVSsr: {
66022cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
66032cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // whether we're in an IT block if the register operands are low
66042cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // registers.
66052cc5cda464e7c936215281934193658cb799c603Jim Grosbach    bool isNarrow = false;
66062cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
66072cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
66082cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(2).getReg()) &&
66092cc5cda464e7c936215281934193658cb799c603Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
66102cc5cda464e7c936215281934193658cb799c603Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
66112cc5cda464e7c936215281934193658cb799c603Jim Grosbach      isNarrow = true;
66122cc5cda464e7c936215281934193658cb799c603Jim Grosbach    MCInst TmpInst;
66132cc5cda464e7c936215281934193658cb799c603Jim Grosbach    unsigned newOpc;
66142cc5cda464e7c936215281934193658cb799c603Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
66152cc5cda464e7c936215281934193658cb799c603Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
66162cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
66172cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
66182cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
66192cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
66202cc5cda464e7c936215281934193658cb799c603Jim Grosbach    }
66212cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.setOpcode(newOpc);
66222cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
66232cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isNarrow)
66242cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
66252cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
66262cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
66272cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
66282cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
66292cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
66302cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (!isNarrow)
66312cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
66322cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
66332cc5cda464e7c936215281934193658cb799c603Jim Grosbach    Inst = TmpInst;
66342cc5cda464e7c936215281934193658cb799c603Jim Grosbach    return true;
66352cc5cda464e7c936215281934193658cb799c603Jim Grosbach  }
6636863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
6637863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
6638863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
6639863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
6640863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
6641863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
6642863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6643863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6644863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
6645863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
6646863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
6647863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
6648863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
6649863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6650863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
6651863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
6652863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
6653863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
6654520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
6655863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
6656863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
6657863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (Ammount == 32) Ammount = 0;
6658863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
6659863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
6660863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
6661863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6662863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6663863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6664520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    if (newOpc != ARM::t2RRX)
6665520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Ammount));
6666863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
6667863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6668863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
6669863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
6670863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
6671863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
6672863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
6673863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
6674863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
667523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
667623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
667723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
667823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
667923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
668023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
668123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
668223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
668323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
668423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
668523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
668623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
668723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
668823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
668923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
669023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
669123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
669223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
669323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
669423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
669523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
669623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
669723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
669823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
669923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
6700ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
6701ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
6702ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
6703ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
6704ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
6705ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
6706ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
6707ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
6708ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
6709ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
6710ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
6711ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
6712ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
671348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
6714ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
6715ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
671671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
6717ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
671871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
671971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
6720ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
6721ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
672271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
672371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
672471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
672571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
672683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
672771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
672848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
672948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
673048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
673148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
673248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
673348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
673448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
673548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
673648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
673748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
673848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
673948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
674048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
67410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
67420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
67430352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
67440352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
67450352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
67460352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
67470352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
67480352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
67490352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
67500352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
67510352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
67520352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
67530352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
67540352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
67550352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
67560352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
67570352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
67580352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
67590352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
67600352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
67610352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
67620352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
67630352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
67640352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
67650352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
67660352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
67670352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
67680352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
67690352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
67700352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
67710352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
67720352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
6773f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
6774f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
6775f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
6776f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
6777f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
6778f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
6779f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
6780f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6781f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6782f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
6783f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
6784f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
6785f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6786f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6787f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
678883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6789f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
6790f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
6791f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
6792f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
6793f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
6794f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
6795f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
6796f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
6797f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
6798f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
6799f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
6800f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
6801f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
6802f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
6803f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6804f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
6805f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
6806f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
6807da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
6808da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
6809da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
6810da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
6811da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6812da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6813da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
6814da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6815da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
6816da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
6817da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
6818da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
6819da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
6820da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
6821da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
6822da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
6823da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
6824da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
682589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
68260f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
68270f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
68280f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
68290f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
683083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
683189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
683283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
683383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
683489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
6835f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
6836f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
6837f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
6838f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
6839f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
684083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
6841f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
684283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
684383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6844f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
6845927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
6846927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
6847927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
6848927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
6849927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
6850927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
6851927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
6852713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
6853713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
6854927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
6855927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
6856927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
6857927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6858927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6859927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
6860927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
6861927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6862927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
6863927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
6864927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
686551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
686651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
686783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
686851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
686983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
687083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
687151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
687251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
687351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
687483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
687551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
687683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
687783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
687851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
6879c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
6880a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
688183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
6882c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
688383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
688483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6885c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
6886395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
6887395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
688883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
6889395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
689083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
689183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
68923ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
689376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
689476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
689576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
689676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
689776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
689876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
689976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
690076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
690176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
690276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
690376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
690476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
690576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
690676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
690776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
690876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
690976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
691076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
691176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
691276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
691376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
691483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
691576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
691676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
691776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
69188213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
69198213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
69208213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
69218213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
69228213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
69238213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
69248213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
69258213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
69268213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
69278213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
692883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69298213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
69308213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
69318213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
69325402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
69335402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
69345402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
69355402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
69365402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
69375402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
693883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
69395402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
69405402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
69415402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
69425402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
69435402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
694483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
69455402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
69465402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
69475402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
69485402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
694983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
69505402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
69515402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
69525402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
69535402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
69545402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
695583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
69565402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
69571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
69581ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
69591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
69601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
69611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
6962c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
6963c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
6964c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
69651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
69661ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
69671ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
69681ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
69691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
69701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
69711ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
69721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
69731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
69741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
69751ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
697683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69771ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
69781ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
69791ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
69801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
69811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
69821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
69831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
69841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
69851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
69861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
69871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
69881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
69891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
69901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
69911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
69921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
69931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
69941ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
69951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
69961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
699783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
69981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
69991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
70001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
7001326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
700250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
700350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
700450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
7005326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
7006326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
7007326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
7008326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
7009326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
7010326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
7011326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
701250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
701350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
701450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
701550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
701650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
701750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
701850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
701950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
7020326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
7021326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
7022326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
7023326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
7024326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
7025326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
7026326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
7027326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
702883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
7029326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
7030326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
7031326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
703204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  case ARM::MOVsi: {
703304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
703404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (SOpc == ARM_AM::rrx) return false;
703504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
703604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      // Shifting by zero is accepted as a vanilla 'MOVr'
703704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      MCInst TmpInst;
703804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
703904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
704004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
704104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
704204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
704304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
704404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      Inst = TmpInst;
704504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      return true;
704604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    }
704704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    return false;
704804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  }
70498d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ANDrsi:
70508d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ORRrsi:
70518d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::EORrsi:
70528d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::BICrsi:
70538d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::SUBrsi:
70548d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ADDrsi: {
70558d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    unsigned newOpc;
70568d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
70578d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (SOpc == ARM_AM::rrx) return false;
70588d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    switch (Inst.getOpcode()) {
7059bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("unexpected opcode!");
70608d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
70618d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
70628d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::EORrsi: newOpc = ARM::EORrr; break;
70638d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::BICrsi: newOpc = ARM::BICrr; break;
70648d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
70658d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
70668d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
70678d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    // If the shift is by zero, use the non-shifted instruction definition.
70688d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) {
70698d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      MCInst TmpInst;
70708d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.setOpcode(newOpc);
70718d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
70728d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
70738d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
70748d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
70758d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
70768d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(6));
70778d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      Inst = TmpInst;
70788d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      return true;
70798d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
70808d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    return false;
70818d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  }
708274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach  case ARM::ITasm:
708389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
708489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
708589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
708689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
708789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
708889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
708989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
709089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
709189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
7092f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
7093f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
709489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
709589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
709689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
709789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
709889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
709989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
710089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
7101f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
7102f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
7103f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
7104f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
7105f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
7106f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
7107f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
7108f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
710989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
711089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
7111f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
711283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
7113f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
7114f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
711547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
711647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
711747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
7118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
71191a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
712047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
712147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
712247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
712347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
712447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
712547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
712647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
712747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
712847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
712947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
713047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
713147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
713247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
713347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
713447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
713547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
7136f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
7137f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
713847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
7139f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
7140f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
7141f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
714247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
7143194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
7144194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
7145194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
7146194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
7147194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
7148194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
7149194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
71504ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
7151194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
7152194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
7153194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
715447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
715547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
715647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
7157fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
7158fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
7159fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7160fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
7161fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
7162fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
716319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
7164193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
7165193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
716619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
7167e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
7168189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
7169189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
7170a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
7171a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
7172a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
7173a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
7174189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
7175a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
7176189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
7177f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
717883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
717983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
718083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
718183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
718283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
7183f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
7184a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
7185a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
7186a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
7187a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
7188a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
718974423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // ITasm is an ARM mode pseudo-instruction that just sets the ITblock and
719074423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    // doesn't actually encode.
719174423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach    if (Inst.getOpcode() == ARM::ITasm)
719274423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach      return false;
719374423e32ce7f426b624bfb0c31481bcf6a36394dJim Grosbach
719442e6bd38e02e2e1c2cc50d2f12036c38c4ea3ab0Jim Grosbach    Inst.setLoc(IDLoc);
7195fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
7196fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
7197e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
7198e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
7199e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
7200e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
7201e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
7202e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
7203e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
7204e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
720516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7206e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
7207e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
7208e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
720916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7210e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
7211e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
7212e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
721347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
7214b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
721588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
721688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
7217f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
7218f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
721947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
722047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
7221194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
7222194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
7223194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
7224194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
7225fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
722616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7227c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
7228fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
7229fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
72301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
7231ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
7232ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
7233ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
72341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
7235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
72361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
72379a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
72389a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
7239515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
72401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
7241515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
72421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
7243515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
72441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
7245a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
7246a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
7247d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".arch")
7248d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveArch(DirectiveID.getLoc());
7249d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".eabi_attribute")
7250d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveEabiAttr(DirectiveID.getLoc());
7251ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
7252ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7253ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
72541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
7255ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
72561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
7257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
7258ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
7259ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
7260ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
7261ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
7262ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7263aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
7264ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7265ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
7266ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
726716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7268ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
7269ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
7270ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
7271b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
7272ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
7273ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
7274ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
7275b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7276ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
7277ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
7278ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
72791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
7280515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
72811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
7282515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
7283515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7284b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7285515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
72869a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
72879a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
72889a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
72899a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
72909a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
72919a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
72929a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
72939a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
72949a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
72959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
72969a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
72979a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
72989a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
72999a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
73009a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
73019a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7302515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7303515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7304515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
7306515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
73071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
73086469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
73096469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
73106469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
7311de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  bool needFuncName = true;
73126469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7313de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Darwin asm has (optionally) function name after .thumb_func direction
73146469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
73156469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
73166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
7317de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    if (Tok.isNot(AsmToken::EndOfStatement)) {
7318de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
7319de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach        return Error(L, "unexpected token in .thumb_func directive");
7320de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Name = Tok.getIdentifier();
7321de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Parser.Lex(); // Consume the identifier token.
7322de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      needFuncName = false;
7323de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    }
73246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
73256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7326de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
7327515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
7328de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach
7329de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Eat the end of statement and any blank lines that follow.
7330de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  while (getLexer().is(AsmToken::EndOfStatement))
7331de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    Parser.Lex();
7332515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
7334de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // We really should be checking the next symbol definition even if there's
7335de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // stuff in between.
7336de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (needFuncName) {
7337d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
73386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
73396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
7340642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
7341642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
7342642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
7343515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7344515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7345515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
7347515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
73481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
734918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7350515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
7351515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
735238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
735358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
7354b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
735558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
73569e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
7357515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7358515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
7359515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7360515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
736118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7362b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7363515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7364515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
7365515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
7366515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7367515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7368515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
73691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
7370515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
73711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
737218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
7373515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
7374515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
737518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
737658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
7377b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
737858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
7379b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
7380515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
7381515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
7382515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7383515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
738418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
7385b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
7386515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
738732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
738898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
7389ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
739098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
739132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
739298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
7393ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
739498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
7395eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
73962a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
7397515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
7398515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
7399515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
7400a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
7401a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
7402a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
7403a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
7404a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
7405a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
7406a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
7407a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7408a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
7409a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7410a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7411a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
7412a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
7413a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7414a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
7415a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
7416a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7417a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7418a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
7419a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7420a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
7421a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
7422a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
7423a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7424a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7425a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7426a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7427a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
7428a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
7429a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
7430a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
7431a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
7432a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
7433a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
7434a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
7435a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
7436a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
7437a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
7438a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
7439d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch
7440d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .arch token
7441d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) {
7442d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7443d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7444d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
7445d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr
7446d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .eabi_attribute int, int
7447d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
7448d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
7449d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
7450d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
745190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
745290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
74539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
7454ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
745594b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
745694b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
745790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
7458ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
74593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
74600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
74610692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
74623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
7463