ARMAsmParser.cpp revision 3a678af71dec76a7e1474ad85a99b3588516906d
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h"
2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h"
3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
33345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
34c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
383a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
39146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbachenum VectorLaneTy { NoLanes, AllLanes, IndexedLane };
4398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
4494b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
48a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Map of register aliases registers via the .req directive.
49a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StringMap<unsigned> RegisterReqs;
50a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
68f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
69f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
70f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
76a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
77a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
78a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
79f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
80f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
84ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
85ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
86ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
890d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
989a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
102a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveReq(StringRef Name, SMLoc L);
103a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  bool parseDirectiveUnreq(SMLoc L);
104d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveArch(SMLoc L);
105d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  bool parseDirectiveEabiAttr(SMLoc L);
106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
10989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
111fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
113ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
115ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
116ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
117ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
118ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
119ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
12047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
12147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
123194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
124194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
125194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
126acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
127acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
128acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
12932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
130ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
131ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
133acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
134acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
135acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1400692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1410692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
14643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
147f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
149f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1538bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1558bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1578bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
166c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
167580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
169293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
171251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1729d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
173862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1747636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
175ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
179a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
180a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
181eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
182eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
183ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
184ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
186ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1879ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
189548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
190548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
192ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
2042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
20614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
207623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
208623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
21088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
21112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
21212431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
21312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
21412431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
2154334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2164334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
2174334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2184334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
220189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
223f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
224d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
225d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
226189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
22847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
229194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
230f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
231194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
232194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
23347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
235ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
23694b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
23832869205052430f45d598fba25ab878d8b29da2dEvan Cheng
239ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
240ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
242f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
244ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
245ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
249189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
25247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
25347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
25816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
25916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2603a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
262a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
264146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2719b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
27721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
278460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
283862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
28498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
28621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
28721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
28821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
28921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
29121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
29524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
3008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
305fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
306fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
31189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
31389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
31589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
31689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
335862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
336862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
337862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
338862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3400aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
341862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
342862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3438155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
344460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
345460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
346460a90540b045c102012da2492999557e6840526Jim Grosbach
347460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
348cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
349cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
35016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3516a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
352a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
353a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
35957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
36057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
361eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
363e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
367f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
368f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
369f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
373580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
374e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
375580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
378e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
379e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
381af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
38292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
38392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
38492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
38592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
386af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
391293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
392293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
393293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
394a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
39516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
396146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
397146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
399762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
400762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
40789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
40889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
414762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
41821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
41924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
421862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
42298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
424862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
425862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
42721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
428fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
429fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4319b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4329b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
43321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
434762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
437706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
438706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
440e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
449a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
45721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
458af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
45992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
46321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
464293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
465293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
466460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
467460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
468460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
470762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
47821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
482fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
484fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
485fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
50024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
503cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
50421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    assert(isImm() && "Invalid access!");
505cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
506cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
508460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
509460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
510460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
511460a90540b045c102012da2492999557e6840526Jim Grosbach  }
512460a90540b045c102012da2492999557e6840526Jim Grosbach
513706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
51421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
515706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
516706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
517706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
523584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
525584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
526584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
527584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
52821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
53121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
53221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
53651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  bool isFPImm() const {
53751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!isImm()) return false;
53851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
53951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    if (!CE) return false;
54051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
54151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    return Val != -1;
54251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  }
5434050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits16() const {
5444050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5454050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5464050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5474050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5484050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 0 && Value <= 16;
5494050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
5504050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  bool isFBits32() const {
5514050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!isImm()) return false;
5524050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5534050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    if (!CE) return false;
5544050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    int64_t Value = CE->getValue();
5554050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    return Value >= 1 && Value <= 32;
5564050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
557a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
55821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
559a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
560a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
561a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
562a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
563a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
56472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
56521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
56672f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
56772f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
56872f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
56972f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
57072f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
57172f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
57221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
57372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57472f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
57572f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
57672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
57772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
57921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
5806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
585587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
58621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
587587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
588587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
590587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
591587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
592587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
59321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
594587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
595587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
596587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
597587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
598587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
59983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
60021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
60183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
60721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
61183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
61283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6137c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
61421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6157c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6167c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6187c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6197c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
620730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
62121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
622730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
623730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
624730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
625730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
626730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
62821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
63521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6393b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
64221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6463b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6473b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6486b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
64921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6506b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6516b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6536b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
65621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6606b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
66321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6676b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
67021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6746b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6763b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
67721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6793b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6813b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
68421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6883b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
69121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6953b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
697f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
69821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
699f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
700f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
701f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
703f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7044a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
70521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7064a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7074a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7094a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
711ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
71221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
713ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
714ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
715ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
716ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
717ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
718fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
71921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
720fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
721fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
722fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
723fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
724fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
725ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
72621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
727ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
728ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
729ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
730ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
731ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
732ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
733ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
734ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
73521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
736ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
737ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
738ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
739ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
740ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
74170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
74221bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
74370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
74470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
74570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
74670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
74770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
748f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
74921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
750f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
751f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
752f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
753f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
754f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
755f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
75621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
757f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
758f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
759f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
761f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7626bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
76321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7646bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7656bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
7666bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
7676bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
7686bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
769e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
77021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
771e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
772e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
773e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
774e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
775e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
7763bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
77721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7783bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7793bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
7803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
7813bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getSOImmVal(-Value) != -1;
7823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
7836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
78421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
7876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
7886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
7896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
79089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
79121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
79289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
79389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
79489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
79589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
79689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
7973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
79821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
7993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getT2SOImmVal(-Value) != -1;
8033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
804c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
80521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
806c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
807c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
808c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
809c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
810c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
81121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
81221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
81321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
81421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
81521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
81621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
81721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
81821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
81921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
82021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
82121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
82221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
82321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
824f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
825430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
826f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
82757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
828f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
83157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
83257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
83357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
8340b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  bool isMemPCRelImm12() const {
8350b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
8360b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8370b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base register must be PC.
8380b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum != ARM::PC)
8390b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach      return false;
8400b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Immediate offset in range [-4095, 4095].
8410b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (!Memory.OffsetImm) return true;
8420b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8430b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8440b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
84557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
84657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
847ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
84957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
851e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
853e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
854e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
857039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
85821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
859039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
860039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
861039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
862039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
863039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
864039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
8652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
8662f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
8672f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
8682f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
86921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
8702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
87157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
873e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
8742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
875e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
877e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
878e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
88221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
8832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
88421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
890251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
891251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
894681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
895681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
896681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
89721bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
898681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
89957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
901e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
903e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
904e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9050da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
906681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9087f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
909e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9117f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
915e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
91757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
92257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
923ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
924ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
925ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
926ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
92757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
929ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
930ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
931e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
932ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
933e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
934ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
935ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
940e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
94157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
94287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
943e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
944e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
94560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
94660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
947e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
94857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
94960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
95060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
951e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
952e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
953ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
954ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
95538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
956e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
95757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
95838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
95938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
960e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
961e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
96238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
96338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
96448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
965e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
96748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
96848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
969e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
970e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
97148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
97248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
973ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
97457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
976ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
977ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
978e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
979e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
980ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
981505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
982a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
9832f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
9842f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
9852f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
98621bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
9872f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return true;
98857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
989a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
991e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
992e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
995b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
99657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
997b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
998b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
999e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1000e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1001b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
100457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1005f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10060b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10070b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
10087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1009e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1010e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10114d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1012f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1013f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
101457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1015f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1016f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1017e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1018e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1020f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1021a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
102257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1023a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
10240b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // Base reg of PC isn't allowed for these encodings.
10250b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Memory.BaseRegNum == ARM::PC) return false;
1026a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1027df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1028e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1029df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1031a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
103257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1033a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1035e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1036e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1037a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1038a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
104009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
104109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
104209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
104321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm() && !isa<MCConstantExpr>(getImm()))
104409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
104509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
104657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1047ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1049e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1050e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10510da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
105421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1056ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
10577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
105863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1059ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
10602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
106121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
10622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10632bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
10652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
10672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
10687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
106921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
107021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
10713483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
10730aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
10740aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
10750aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
10760aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
10770aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
10780aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1079862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
10800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1081862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1082862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1084280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  bool isVecListTwoD() const {
10850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1086280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    return VectorList.Count == 2;
1087280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
1088280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
1089cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
10900aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1091cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1092cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1093cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1094b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
10950aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1096b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1097b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1098b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
10994661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  bool isVecListTwoQ() const {
11000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11010aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return VectorList.Count == 2;
11024661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  }
11034661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach
11043471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isSingleSpacedVectorAllLanes() const {
11053471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && !VectorList.isDoubleSpaced;
11063471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11073471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isDoubleSpacedVectorAllLanes() const {
11083471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return Kind == k_VectorListAllLanes && VectorList.isDoubleSpaced;
11093471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
111098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
11113471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
111298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
111398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
111498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
111513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  bool isVecListTwoDAllLanes() const {
11163471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isSingleSpacedVectorAllLanes()) return false;
11173471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    return VectorList.Count == 2;
11183471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  }
11193471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach
11203471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach  bool isVecListTwoQAllLanes() const {
11213471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    if (!isDoubleSpacedVectorAllLanes()) return false;
112213af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
112313af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
112413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
112595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isSingleSpacedVectorIndexed() const {
112695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && !VectorList.isDoubleSpaced;
112795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
112895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isDoubleSpacedVectorIndexed() const {
112995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return Kind == k_VectorListIndexed && VectorList.isDoubleSpaced;
113095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
11317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
113295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
11347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
11357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1136799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
113795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1138799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1139799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1140799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1141799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
114295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1143799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1144799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1145799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
11469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
114795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
11499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
11509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1151799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
115295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
115395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
115495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
115595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
115695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQWordIndexed() const {
115795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
115895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
115995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  }
116095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach
116195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach  bool isVecListTwoQHWordIndexed() const {
116295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
1163799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1164799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1165799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1166799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
116795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
1168799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1169799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1170799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
11713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDByteIndexed() const {
11723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 7;
11743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
11753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
11763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDHWordIndexed() const {
11773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
11793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
11803a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
11813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQWordIndexed() const {
11823a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
11833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
11843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
11853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
11863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeQHWordIndexed() const {
11873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isDoubleSpacedVectorIndexed()) return false;
11883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 3;
11893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
11903a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
11913a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  bool isVecListThreeDWordIndexed() const {
11923a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    if (!isSingleSpacedVectorIndexed()) return false;
11933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return VectorList.Count == 3 && VectorList.LaneIndex <= 1;
11943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
11953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
1196460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1197460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1198460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1199460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1200460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1201460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1202460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1203460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1204460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1205460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1206460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1207460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1208460a90540b045c102012da2492999557e6840526Jim Grosbach
12090e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
121021bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12110e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12120e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
12130e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
12140e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
12150e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
12160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
12170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
12180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1219460a90540b045c102012da2492999557e6840526Jim Grosbach
1220ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
122121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1222ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1223ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1224ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1225ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1226ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1227ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1228ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1229ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
12306248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
123121bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12326248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12336248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
12346248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
12356248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
12366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
12376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
12386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
12396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
12406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
12416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
12426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
12436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
124421bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
12476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
12486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
12496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
12506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
12516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
12526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
12536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
12546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
12556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
12566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
12576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
12589b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  bool isNEONi32vmovNeg() const {
125921bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
12609b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12619b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // Must be a constant.
12629b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (!CE) return false;
12639b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    int64_t Value = ~CE->getValue();
12649b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
12659b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
12669b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    return (Value >= 0 && Value < 256) ||
12679b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
12689b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
12699b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
12709b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
12719b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
12729b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
12736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1274f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
127521bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (!isImm()) return false;
1276f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1277f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1278f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1279f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1280f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1281f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1282f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1283f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1284f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1285f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
12863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
128714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
128814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
128914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
129014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
12913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
12923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
12933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
12943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
12953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
12968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1297345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
12988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
129904f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
130004f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
13018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
13028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1305fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1306fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1307fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
13089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
13099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
13119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
13139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
13149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
13169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
13179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
131889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
131989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
132089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
132189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
132289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
132389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
132489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
132589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
132689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
132789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1328d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1329d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1330d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1331d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1332d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1334a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1337a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1338af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1339e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1340430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1341430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1342af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1343af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1344e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1345af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1346e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1347e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1348af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1349152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1350430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1351430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1352af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
135392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1354af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
135592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
135692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1357580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
13580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1359580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1360580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
13610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
13620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
136387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
13647729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
13655fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
13665fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
13677729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
13687729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
136987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
137087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
13710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
13720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
13730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
13740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
13750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
13760f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
13770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
13780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
13797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
13807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
13827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
13837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
13847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1385293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1386293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1389293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1391293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1392293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1393293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1394293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1395293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
13963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
13976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
13996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
14006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
14014050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits16Operands(MCInst &Inst, unsigned N) const {
14024050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14034050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14044050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(16 - CE->getValue()));
14054050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14064050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14074050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  void addFBits32Operands(MCInst &Inst, unsigned N) const {
14084050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14094050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14104050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(32 - CE->getValue()));
14114050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach  }
14124050bc4cab61f8d3c7583a9b60f17c7da47bbf69Jim Grosbach
14139d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
14149d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
141551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
141651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    int Val = ARM_AM::getFP32Imm(APInt(32, CE->getValue()));
141751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14189d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
14199d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1420a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1421a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1422a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1423a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1424a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1425a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1426a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1427a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
142872f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
142972f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
143072f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
143172f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
143272f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
143372f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
143472f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
143572f39f8436848885176943b0ba985a7171145423Jim Grosbach
143672f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
143772f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
143872f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
143972f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
144072f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
144172f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
144272f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
144372f39f8436848885176943b0ba985a7171145423Jim Grosbach
1444f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1445f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1446f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1447f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1448f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1449f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1450f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1451f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
14524a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
14534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14544a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
14554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
14564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
14584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
14594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
146070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
146170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
146270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
146370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
146470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
146570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
146670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1467ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1468ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1469f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1470f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1471f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1472f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1473f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1474f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1475f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1476f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1477f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
147889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
147989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
148089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
148189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
148289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
148389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
148489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
148589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
14863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
14873bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14883bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
14893bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
14903bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14913bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
14923bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
14933bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1494e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1495e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1496e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1497e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1498e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1499e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1500e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1501e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
15023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
15033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15043bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
15053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
15063bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15073bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
15083bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
15093bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1510706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1511706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1512706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1513706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1514706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
15157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
15167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1517e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1518505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1519505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
15200b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  void addMemPCRelImm12Operands(MCInst &Inst, unsigned N) const {
15210b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
15220b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    int32_t Imm = Memory.OffsetImm->getValue();
15230b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    // FIXME: Handle #-0
15240b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
15250b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
15260b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  }
15270b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach
152857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
152957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
153057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
153157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
153257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
153357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
15347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
15357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1536e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1537e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
15387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
15397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
15407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
15417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
15427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
15437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
15447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
15457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1546e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1547e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1548ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1549e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1550e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
15517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1552ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1553ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1554039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1555039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1556039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1557039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1558039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1559039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1560039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1561039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1562039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1563039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1564039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1565039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1566039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1567039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
15682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
15692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
15702f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
15712f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
15722f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
15732f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
15742f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
15752f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
15762f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
15772f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
15782f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
15792f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1580e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1581e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
15822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
15832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
15842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
15852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
15862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
15872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
15882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
15892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1590e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
15912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1592e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1593e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
15942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
15962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
15972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
15982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
159921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
16002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
16012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
16022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
16032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1604251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
16052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
16062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
16082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
16092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
16102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
16122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1614251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
16152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
16162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
16182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
16197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
16207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1621681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1622681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1623681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1624681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1625681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1626681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1627681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1628681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1629681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
16307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1631e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
16327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
16337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
16347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
16357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
16367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1637e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
16387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
16407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1641a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1642a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
16432f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
16442f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
16452f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    // and we reject it.
16462f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    if (isImm()) {
16472f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
16482f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
16492f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach      return;
16502f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach    }
16512f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach
1652e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1653e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1654a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1655a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1656a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1657b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1658b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1659b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1660e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1661e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1662b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1663b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1664b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
16657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
16667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1667e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1668e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
16697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1671ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1672f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1673f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1674f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1675f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1676a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1677f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1678a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1679a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1680a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1681a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1682a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
168321bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
1684a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1685a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1686a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1687a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1688a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1689a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1690e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1691e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1692a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1693a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1694a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
16957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
16967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
169709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
169821bcca81f4597f1c7d939e5d69067539ff804e6dJim Grosbach    if (isImm()) {
169909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
170009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
170109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
170209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
170309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
170409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1705e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1706e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
17077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
170992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
17107f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
17117f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1712e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1713e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17167f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
17177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1718e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1719e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
17217f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
17227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
17237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1724430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1725430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1726430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1727e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1728e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
17297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
17307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1731d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1732ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1733ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1734e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1735e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1736e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1737ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1738ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
17397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
17407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1741e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1742e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
174314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
17443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
174560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
174660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1747e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1748e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
174960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
175048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
175148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
175238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
175338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1754e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1755e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
175638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
175738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
175838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
175948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
176048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1761e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1762e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
176348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
176460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
176560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1766ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1767ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1768e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1769e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1770ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1771ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1772ecd858968384be029574d845eb098d357049e02eJim Grosbach
17737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
17747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
17777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
17787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
177963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
17807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
17817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1782f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1783ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
17842bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
17852bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
17862bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17872bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
17882bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
17892bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
17902bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
17912bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
17922bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
17932bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
17942bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
17952bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
17967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
17977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
17987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1799f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1800f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1801f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1802f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1803f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1804f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1805f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1806f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1807f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1808f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1809f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1810f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1811ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1812ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1813584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1814584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1815584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1816584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1817584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1818a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1819a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1820a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1821a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1822a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
18236029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1824862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1825862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1826862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1827862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
18287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
18297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
18307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
18317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
18327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
18337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1834460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1835460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1836460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1837460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1838460a90540b045c102012da2492999557e6840526Jim Grosbach
1839460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1840460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1841460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1842460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1843460a90540b045c102012da2492999557e6840526Jim Grosbach
1844460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1845460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1846460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1847460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1848460a90540b045c102012da2492999557e6840526Jim Grosbach
18490e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
18500e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
18520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
18530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
18550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
18560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1857ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1858ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1859ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1860ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1861ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1862ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1863ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1864ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1865ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1866ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1867ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1868ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
18696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
18706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
18726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
18746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
18756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
18766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
18776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
18786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
18796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
18806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
18816248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
18826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
18836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
18846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
18866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
18876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
18886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
18896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
18906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
18916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
18926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
18936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
18949b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
18959b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  }
18969b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach
18979b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach  void addNEONi32vmovNegOperands(MCInst &Inst, unsigned N) const {
18989b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
18999b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    // The immediate encodes the type of constant as well as the value.
19009b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
19019b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    unsigned Value = ~CE->getValue();
19029b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
19039b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
19049b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
19059b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
19069b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach    else if (Value > 0xffffff)
19079b0878512fb57ee4b0bc483509e4d9f4f0b9e426Jim Grosbach      Value = (Value >> 24) | 0x600;
19086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
19096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
19106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1911f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1912f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1913f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1914f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1915f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1916f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1917f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1918f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1919f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1920f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1921f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1922f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1923b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1924b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
192589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
192621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
192789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
192889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
192989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
193089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
193189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
193289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
19333a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
193421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1935345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1936345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1937345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
19383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1939345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1940345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1941fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
194221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1943fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1944fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1945fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1946fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1947fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1948fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1949fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
195021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
1951fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1952fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1953fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1954fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1955fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1956fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
19579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
19589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
19599b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
19609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
19619b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
19629b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
19639b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
19649b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
1965d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
196621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
1967d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1968d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1969d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1970d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1971d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1972d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
19733a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
197421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
1975762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1976762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1977762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1978762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
19793a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1980a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1981a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
198250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
198321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
1984762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1985762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1986762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
19873a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1988a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1989a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1990e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1991e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1992e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1993e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1994e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
199521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
1996af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1997af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1998af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1999af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
2000e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
2001e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
2002e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
2003e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2004e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
200592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
200692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
200792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
200892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
200921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
2010af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
2011af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
2012af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
201392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
201492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
201592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
201692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
201792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
2018580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
20190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
202021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
2021580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
2022580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
20230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
20240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
20250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
20260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
20270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
20287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
202921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
20307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
20317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
20327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
20337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
20347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
20357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2036293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
2037293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
203821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
2039293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
2040293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
2041293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
2042293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
2043293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
2044293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2045293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
20467729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
20475fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
2048cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
204921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
20500f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
2051d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
205221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
2053d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
2054275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
205521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
20560f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
20570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
20585fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
20597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
206024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
2061cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
2062cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
2063cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
20648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
20658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
20668d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
2067862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
20680aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
2069862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
2070862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
2071862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
20720aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
2073862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
2074862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
2075862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
2076862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2077862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
207898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
20793471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                              bool isDoubleSpaced,
208098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
208198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
208298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
208398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
20843471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
208598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
208698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
208798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
208898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
208998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
20907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
209195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             unsigned Index,
209295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             bool isDoubleSpaced,
209395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                             SMLoc S, SMLoc E) {
20947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
20957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
20967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
20977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
209895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
20997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
21007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
21017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
21027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
21037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
2104460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
2105460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
2106460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
2107460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
2108460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
2109460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
2110460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
2111460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2112460a90540b045c102012da2492999557e6840526Jim Grosbach
21133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
211421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
2115762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
2116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2117762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2119cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2120cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
21217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
21227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
21237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
21247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
21250d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
212657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
21277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
21283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
212921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2130e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2131e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2132e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2133e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2134e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
213557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2136e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
21377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
21387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
21397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
21407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
214116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2142f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2143f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2144f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
21457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
214621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
21477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2148f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2149f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2150f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2151762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2152762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
21533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2155706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2156706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
215721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2158706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2159706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2160706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2161706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2163a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2164a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
216521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2166a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2167a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2168a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2169a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2170a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2171584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2172584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
217321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2174584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2175584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2176584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2177584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2178584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2183b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2184fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
218521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
21866a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2187fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
218821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2189d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2190d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
219121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
21921a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    static const char *MaskStr[] = {
21931a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
21941a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
21951a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
219689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
219789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
219889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
219989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
220021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2201fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2202fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
220321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2204fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2205fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
22069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
22079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
22089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
220921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2210584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
221221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2213fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2214fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
221521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2216706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2217706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
221821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
22196ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2220e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
22216ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2222fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
222321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2224f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2225f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2226f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2227f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2228f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2229f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
22307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
223121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2232a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2233a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2234a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2235a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2236a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2237a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2238a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2239a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
224021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
224150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2242fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
224321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2244580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2245580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
224721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
224892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2249efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2250efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2251efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
22520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
225321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
225492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2255efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2256efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2257efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
225892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
225921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
22607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
22617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
226221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2263293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2264293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2265293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
226621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
226721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
226821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
22698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
22708d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
22715fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
22725fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
22737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
22747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
22757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
22768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
22778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
22788d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
22798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
22808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2281862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2282862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2283862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2284862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
228598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
228698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
228798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
228898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
22897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
22907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
22917636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
22927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
229321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2294fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2295fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2296460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2297460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2298460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2299fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2300fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
23013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
23033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
23043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
23063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
23083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
230969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
231069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2311a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
23121355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2313a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2314bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2315bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2316bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2317bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
23189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2319e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2320e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
23213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
23221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
232318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
23247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2325d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2326590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
23270c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
23280c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
23290c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
23300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
23310c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
23320c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
23330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
233440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
233540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
233640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
233740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
233840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
233940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
234040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
234140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
234240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
234340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
234440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
234540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
234640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
234740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
234840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
234940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
23500c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
23510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2352a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2353aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // Check for aliases registered via .req. Canonicalize to lower case.
2354aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // That's more consistent since register names are case insensitive, and
2355aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    // it's how the original entry was passed in from MC/MCParser/AsmParser.
2356aee718beac4fada5914d773db38002d95cae5e0dJim Grosbach    StringMap<unsigned>::const_iterator Entry = RegisterReqs.find(lowerCase);
2357a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2358a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2359a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2360a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2361a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2362a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
236369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2364b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2365460a90540b045c102012da2492999557e6840526Jim Grosbach
2366e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2367e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2368d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
236919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
237019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
237119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
237219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
237319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
23740d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
23750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
23770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
23780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
23790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2380590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
23810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2382af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
23830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
23840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
23850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
23860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
23870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
23880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
23890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
23900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
239119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
23920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2393e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2394e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2395e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2396e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2397e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2398eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2399e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2400e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2401e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2402e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2403e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2404e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2405e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2406e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2407e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2408e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2409e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2410e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
24118a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
24128a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2413e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2414e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2415e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
241619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
241719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
241819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
241919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2420e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2421e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
242219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
242319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
242419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
242519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2426e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2427e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2428e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2429e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2430e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2431e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2432e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
243319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
243419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2435e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2436de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // shift by zero is a nop. Always send it through as lsl.
2437de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      // ('as' compatibility)
2438de626ad8726677328e10dbdc15011254214437d7Jim Grosbach      if (Imm == 0)
2439de626ad8726677328e10dbdc15011254214437d7Jim Grosbach        ShiftTy = ARM_AM::lsl;
2440e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
24411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2442e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
244319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
244419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
244519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
244619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
244719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
244819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2449e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
245019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
245119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2452e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2453e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
245492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
245592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2456af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
24570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
245892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
245992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
246092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
24610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
246219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
24630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
24640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
24650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
246650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
246750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
246850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2469e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2470e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2471e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
247250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
24731355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2474e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
24751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2476e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
247750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2478d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
247950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2481e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2482e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
248350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
248450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2485e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2486460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2487460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2488460a90540b045c102012da2492999557e6840526Jim Grosbach
2489460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2490460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2491460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2492460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2493460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2494460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2495460a90540b045c102012da2492999557e6840526Jim Grosbach
2496460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2497460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
2498460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2499460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2500460a90540b045c102012da2492999557e6840526Jim Grosbach    if (!MCE) {
2501460a90540b045c102012da2492999557e6840526Jim Grosbach      TokError("immediate value expected for vector index");
2502460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2503460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2504460a90540b045c102012da2492999557e6840526Jim Grosbach
2505460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2506460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2507460a90540b045c102012da2492999557e6840526Jim Grosbach      Error(E, "']' expected");
2508460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2509460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2510460a90540b045c102012da2492999557e6840526Jim Grosbach
2511460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2512460a90540b045c102012da2492999557e6840526Jim Grosbach
2513460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2514460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2515460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
251699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
251799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
251850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2519a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2520a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2521fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2522fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2523fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2525e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2526e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2527e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
25284d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  default: return -1;
2529e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2530fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2531e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2532e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2533e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2534e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2535e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2536e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2537e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2538e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2539e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2540e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2541e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2542e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2543e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2544e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2545e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2546fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2547e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2548e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2549e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2550e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2551e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2552e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2553e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2554e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2555e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2556e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2557e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2558e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2559e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
256089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
256189df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
256289df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
256389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
256489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
256589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
256689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
256789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
256889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
256989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
257089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
257189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
257289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
257389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
257489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
257589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
257689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
257789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
257889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
257989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
258089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
258189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
258289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
258389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
258489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
258589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
258689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
258789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
258889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
258989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
259089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
259189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
259289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
259389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
259489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
259543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2596fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2597fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2598f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
259943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2600e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2601e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2602c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2603c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2604e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2605fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2606e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2607f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2608e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2611f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2613fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
261443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2615fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2616fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2617f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
261843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2619fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2620fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2621c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2622c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2623fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2624fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2625fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2626f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2627fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2628fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2629fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2630f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2631e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2632e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
26339b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
26349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
26359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
26369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
26389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
26409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
26419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
26429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
26439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
26459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
26469b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
26479b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
26489b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
26499b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
26509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
26519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
26529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
26539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
26549b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
26559b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
26569b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
26589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
26599b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
26609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
26619b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
26629b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
26639b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
26649b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
26659b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
26669b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2667d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2668d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2669d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2670d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2671d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2672d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2673d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2674d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2675d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2676d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2677d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
2678d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2679d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2680d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2681d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2682d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2683d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2684d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2685d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2686d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2687d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2688d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2689ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2690ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2691ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2692ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2693ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2694ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2695ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2696ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2697ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2698ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2699ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2700ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2701ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
270225e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2703ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2704ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2705ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2706ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2707ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2708ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2709ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2710ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2711ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2712d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
271350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
27141355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
271518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2716a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2717e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2718d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2719d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
272016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2721d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2722d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2723d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2724d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2725d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2726d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2727ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2728ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2729ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2730ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2731ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2732ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2733ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2734ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2735ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2736ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
27371a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2738d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2739d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2740d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2741d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2742d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2743d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2744d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2745d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2746e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2747ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2748d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2749d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2750d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2751d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2752d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2753d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2754d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2755d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2756e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2757d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2758d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2759d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2760d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2761ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2762ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2763ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2764d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2765d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2766d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2767d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2768d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2769d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2770d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2771d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2772d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2773d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2774d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2775d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2776d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2777d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2778d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2779d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2780d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2781d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2782d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2783d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2784d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2785a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2786d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2787d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
27882d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2789ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2790ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2791ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2792ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2793ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2794ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2795d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2796d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2797d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2798d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2799a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg))
2800d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2801a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) {
2802a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2803a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2804a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2805a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2806d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2807d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2808d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2809d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2810d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2811d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2812d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2813ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2814ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2815d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2816d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2817d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2818d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2819d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2820d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2821e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
282227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
282350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
282427debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
282527debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
282627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
282727debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
282827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
282927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
283027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
283150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2832d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2833d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
283498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
283598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
28367636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
28377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
283898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
283998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
284098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
284198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
284298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
284398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
284498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
284598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2846c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCExpr *LaneIndex;
2847c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    SMLoc Loc = Parser.getTok().getLoc();
2848c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (getParser().ParseExpression(LaneIndex)) {
2849c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "illegal expression");
2850c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
28517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
2852c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LaneIndex);
2853c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (!CE) {
2854c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Loc, "lane index must be empty or an integer");
2855c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2856c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2857c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2858c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "']' expected");
2859c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2860c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2861c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Parser.Lex(); // Eat the ']'.
2862c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    int64_t Val = CE->getValue();
2863c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach
2864c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    // FIXME: Make this range check context sensitive for .8, .16, .32.
2865c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    if (Val < 0 || Val > 7) {
2866c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      Error(Parser.getTok().getLoc(), "lane index out of range");
2867c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach      return MatchOperand_ParseFail;
2868c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    }
2869c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    Index = Val;
2870c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    LaneKind = IndexedLane;
2871c931325d99a93c273844c38d3c762705c454ae93Jim Grosbach    return MatchOperand_Success;
287298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
287398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
287498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
287598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
287698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
2877862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2878862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2879862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
288098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
28817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
28825c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
28835c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
28845c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
28855c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
28865c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
28875c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
28885c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
28895c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
28905c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
28915c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
28927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
289398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
289498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
289598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
289698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
289798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
28980aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
289998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
290098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
290198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29023471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, false,
29033471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
290498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
290795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
290895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
291098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
29115c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
29125c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
29135c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
29145c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
29157636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
291698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
291798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
291898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
291998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
292098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29210aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
292298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
292398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
292498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
29253471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, false,
29263471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                                S, E));
292798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
29287636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
29297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
293095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               LaneIndex,
293195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                               false, S, E));
29327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
293398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
29345c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
29355c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
29365c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
29375c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
29385c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
29395c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
29405c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
2941862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
2942862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2943862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
2944862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
2945862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2946862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
2947862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
2948862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
2949862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2950862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2951862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
2952276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
2953c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
2954c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
2955c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
2956c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2957c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
29580aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
29590aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
2960c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
2961c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
2962c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
29637636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
296498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
2965c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
2966e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2967e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2968e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
29690aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
29700aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
29710aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
29720aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
29730aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
29740aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
29750aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
2976e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2977e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2978e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
2979e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
2980e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
2981e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2982e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
2983e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2984e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2985e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2986e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
2987e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
2988e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
2989e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
2990e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
2991e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
2992e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
2993e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2994e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
2995e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
2996e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
2997e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
2998e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2999e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
300098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
300198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
30027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
30037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
300498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
30057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
300698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
300798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
300898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
300998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
3010e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
3011e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
3012e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
3013e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
3014e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
3015e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
3016862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
3017862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
3018862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
3019862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
3020862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
3021862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
3022862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3023862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3024c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
3025862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
3026862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
3027c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
3028c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
3029c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
3030c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
30310aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
30320aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
30330aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
30340aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
30350aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
30360aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
30370aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
3038c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
3039c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
3040c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
3041c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
3042c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
3043c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
3044c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
304598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
304698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
30477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
304898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
30497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
305098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
30517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
305298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
305398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
305498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
3055c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
3056c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
30570aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
30580aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
30590aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
30600aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
30610aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
30620aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
30630aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
30640aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
3065862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
3066862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
3067862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
3068862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
306998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
307098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
30717636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
307298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
30737636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
307498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
30757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
307698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
307798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
307898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
3079862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3080862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3081862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3082862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
3083862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
3084862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
3085862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
3086862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
3087862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
308898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
308998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
30900aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
30910aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
309298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
309398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
309498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
30953471d4fbbd50eabb12511b711cbd2afd7bb9d962Jim Grosbach                                                            (Spacing == 2),
309698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
309798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
30987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
30997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
310095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           LaneIndex,
310195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           (Spacing == 2),
310295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                                           S, E));
31037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
310498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
3105862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
3106862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
3107862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
310843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
3109f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
311043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3111706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3112706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3113706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3114706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
3115706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3116706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
3117706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
3118706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
3119032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
3120706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
3121032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
3122706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
3123706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
3124032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
3125706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
3126032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
3127706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
3128706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
3129706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
3130706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3131706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
3132f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
3133706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3134706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3135706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3136f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3137706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3138706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
313943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3140a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
314143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3142a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3143a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3144a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3145a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3146a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
31472dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
31482dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3149a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
31502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
31512dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
31522dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
31532dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
31542dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
31552dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
31562dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
31572dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
31582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
31592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
31602dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
31612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
31622dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
31632dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
31642dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3165a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3166a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3167a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3168a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3169a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3170584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3171584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
317243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3173584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
317443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3175584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3176584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3177584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3178584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3179584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3180acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3181acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3182acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
3183acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
3184acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
3185acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
3186acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
3187acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
3188acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
3189acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
3190acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
3191acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
3192acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
3193acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
3194acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
3195acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
3196acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
3197acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
319818c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3199acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3200acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3201acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3202acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
3203acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3204acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
320518c8d12dea944086ef0ce2f674ca8a34de2bbd74Jim Grosbach
3206acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3207acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3208acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3209acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3210acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3212584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3213584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3214590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3215584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3216584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3217584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3218584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3219584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3220584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3221584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3222584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3223584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3224584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3225b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3228584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
32304b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3232584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3234bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
32354b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
323756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
323856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3240584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3242584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3244584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3245584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3246584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3252584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3254584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3255584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
32567784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
32577784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
32587784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
32597784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
32607784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
32617784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
32627784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3263584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3264584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3265584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3266584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3267584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3268584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3269584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3270584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3271a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3272a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3273f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3274f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3275f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3276f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3277f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3278f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3279f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3280f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3281f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3282590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3283590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3284f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3285f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3286f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3287f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3288f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3289f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3290f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
32918a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
32928a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3293f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3294f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3295f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3296f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3297f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3298f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3299f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3300f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3301f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3302f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3303f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3304f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3305f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3306f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3307f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3308f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3309f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3310f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3311f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3312f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3313f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3314f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3315f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3316f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3317f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3318f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3319f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3320c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3321c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3322c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3323c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3324c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3325c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3326c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3327c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3328c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3329c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3330c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3331c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3332c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3333c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3334c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3335c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3336c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3337c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3338c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3339c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3340c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3341c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3342c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3343c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3344580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3345580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3346580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3347580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3348580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3349580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3350580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3351580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3352580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3353580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3354580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3355580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3356580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3357580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3358580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3359580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3360580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3361580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3362580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3363580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3364580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3365580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3366580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3367580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3368580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3369580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
33708a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33718a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3372580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3373580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3374580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3375580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3376580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3377580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3378580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3379580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3380580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3381580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3382580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3383580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3384580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3385580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3386580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3387580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3388580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3389580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3390580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3391580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3392580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3393580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3394580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3395580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
33960afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
33970afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
33980afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
33990afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
34000afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3401580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3402580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3403580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3404580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3405580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3406580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3408580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3409580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3410580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3411580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3412580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3414580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
34167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
34177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
34187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
34197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
34207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
34217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
34227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3423326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3424326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
34257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3426326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3427326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
34287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
34297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
34318a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
34328a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
34337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
34347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
34367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
34377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
34397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
34407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
34417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
34427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
34447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
34457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
34467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
34477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
34497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
34517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
34527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
34537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
34547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
34557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
34567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
34577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
34587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
34607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
34617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
34627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
34637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
34647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3465293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3466293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3467293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3468293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
34698a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
34708a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3471293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3472293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3473293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3474293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3475293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3476293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3477293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3478293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3479293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3480293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3481293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3482293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3483293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3484293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3485293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3486293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3487293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3488293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3489293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3490293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3491293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3492293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3493293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3494293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3495293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3496293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3497293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3498293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3499293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3500293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3501293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
35028a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
35038a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3504293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3505293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3506293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3507293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3508293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3509293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3510293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3511293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3512293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3513293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3514293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3515293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3516293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3517293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3518293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3519293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3520293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3521293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3522293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3523293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3524293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3525293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3526293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3527293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3528293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3529293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3530293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3531293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3532293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
35337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
35347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
35357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3536f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3537f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3538f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
35397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
35407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
35417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
35427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
35437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
35447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
35457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
354616578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
35477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
35487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
35497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
35507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
35517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
35527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
355316578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
35547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
35557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
35567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
35577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
35587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
35597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
35607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
35617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
35627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
35637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
35647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
35657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3566f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3567f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
35680d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
35690d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
35700d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
35710d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
35720d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3573f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3574f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3575f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
35767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
35777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
35787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
35797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3580251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3581251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3582251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3583251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3584251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3585251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3586251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3587251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3588251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3589251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3590251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3591251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3592251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3593251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3594251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3595251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3596251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
35978a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
35988a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3599251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3600251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3601251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3602251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3603251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3604251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3605251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3606251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3607251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3608251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3609251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3610251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3611251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3612251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3613251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3614251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3615251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3616251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3617251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3618251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3619251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3620251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3621251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3622251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3623251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3624251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3625251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3626251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3627251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3628251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3629251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3630251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3631251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3632251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3633251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3634251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3635251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3636251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3637251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3638251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3639251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3640251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3641251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3642251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3643251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3644251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3645251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3646251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3647251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3648251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3649251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3650251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3651a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3652a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3653a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3654a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3655a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3656a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3657a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3658a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3659a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3660a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3661a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3662a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3663a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3664a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3665a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3666a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3667a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3668a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3669a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3670a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3671a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3672a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3673a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3674a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3675a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3676a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3677a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3678a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3679a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3680a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3681a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3682a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3683a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3684a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3685a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3686a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3687eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3688eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3689eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3690eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3691eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3692eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3693eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3694eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3695eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3696eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3697eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3698eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3699eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3700eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3701eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3702eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3703ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3704ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3705ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3706ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3707ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3708ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3709ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3710ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3711ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3712ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3713ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3714ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3715ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3716ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
37171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3718ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3719ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3720ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
37211355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3722ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3723ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3724ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3725ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3726ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3727ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
37287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3729ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3730ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3731ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3732ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
37339ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
37349ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
37359ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
37369ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
37379ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
37389ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37399ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
37409ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
37419ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
37429ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
37439ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
37449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
37459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
37479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
37489ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
37499ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3750548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3751548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3752548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3753548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3754548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3755548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3756548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3757548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3758548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3759548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3760548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3761548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3762548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3763548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
37641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3765ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3766ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3767ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
37681355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3770ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3771ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3772548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3773548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3774548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
37767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
37777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
37787b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
37797b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
37807b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
37817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
37827b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
37837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
37857b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
37867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
37877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
37887b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37897b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
37907b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
37917b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
37927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
37937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
37947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
37957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
37967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
37977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3799ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
38017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
38067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3807ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3808ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3809ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3810ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
38117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3812ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3813ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3814ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
38157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
38167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3818aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3819ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3820ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
38217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
38257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
38267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
38287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3829aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
38307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
38317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
38337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
38347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
38357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
38377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
38397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
38447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3845ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3846ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3847ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3848ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
38497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3850ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3851ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3852ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
38537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
38547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3855ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3856ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
38577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3858ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
38607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
38617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
38627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
38637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3865ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3866ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3867ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
38682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
38692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
38702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
38712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
38722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
38732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
38752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
38762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
38772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
38782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
38802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
38812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
38822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
38842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
38852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
388614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
388714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
388814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
388914605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
389014605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
389114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
389214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
389314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
389414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
389514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
389614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
389714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
389814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
389914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
390014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
390114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
390214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
390314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3904623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3905623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3906623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3907623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3908623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3909623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3910623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3911623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3912623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3913623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3914623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3915623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
3916623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
3917623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
391888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
391988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
392088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
392188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
392288ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
392388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
392488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
392588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
392688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
39277a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
39287a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
39297a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
39307a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
393188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
39327a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
393388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
393488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
393588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
393688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
39371b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
39381b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
39391b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
39401b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
39411b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
39421b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
39431b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
39441b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
39451b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
394688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
394788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
394888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
394988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
3950623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
395112431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
395212431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
395312431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
395412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
39556029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
395612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
395712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
395812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
395912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
396012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
396112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
396212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
396312431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
396412431329d617064d6e72dd040a58c1635cc261abJim Grosbach
396512431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
396612431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
396712431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
396812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
39696029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
397012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
397112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
397212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
397312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
397412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
397512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
397612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
397712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
397812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
397912431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
398012431329d617064d6e72dd040a58c1635cc261abJim Grosbach
39814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
39824334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
39834334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
39854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
39864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
39874334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
39884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
39896029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
39904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
39914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
39924334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
39934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
39944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
39954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
39964334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
39974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
39984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
39994334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
40004334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
40014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
40024334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
40034334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
40044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
40056029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
40064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
40074334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
40084334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
40094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
40104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
4011e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
40129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
401350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
40147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4015762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
401618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
4017a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
4018762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
4019b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
4020a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
402118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
40221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
40237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
40247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
4025a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
40270571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
40280571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
40297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
40300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
40317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
4032762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
4033b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
4034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
403657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
403703f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
4038fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
4039fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
4040fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
4041fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4042fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
4043fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
4044fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
40467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
404750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
40487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
40497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
405050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
405157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
405257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
405357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
405457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
405557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
405657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
405757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
405857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
405957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
406057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
406157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
406257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
406357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
406457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
406557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
406657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
406757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
406857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
406957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
4070eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
4071eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
4072eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
4073eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
407457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
407557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
407657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
407757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
407857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
407957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
408057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
408157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
408257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
408357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
408457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
408557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
408657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
408757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
408857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
408957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
409057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
409157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
409257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
409357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
409457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
409557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
409657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
409757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
409857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
409957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
410057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
410157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
41026cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
41036cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
41046cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
41058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
41066cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
41078a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
41086cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
41097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
411050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
41110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
41127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
41137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
41147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
411505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
41167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
41177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
41187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
41197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
41207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
41217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
41227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
41240da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
41250da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
41260da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
41270da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
41287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
41297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
41307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
41317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
41327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
413305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
41347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
41357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
41367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
413757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
413857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4139a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
41417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
41427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
41437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
41447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4145762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
41467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
41489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4149d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
41507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
41517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
41527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
41537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
41547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
41557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
41567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
41577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
41587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
41599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
41607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
41617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
41627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
41637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
41647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
41667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
41670d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
41687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
41697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
41700d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
41717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
41729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
417316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
41747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
41757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
41767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
41777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
41787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
41797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
41807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
418157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
41827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
41837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4184f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4185f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4186f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4187f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4188f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4189f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
41909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
41919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
41929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
41939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
41947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4195a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4196a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
41977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
41987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
41997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
42007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
420118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4203a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
420438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4205af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4206af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
42070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
42090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
42110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
42130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
42150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
42177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4218b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
42217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
42227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
42237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
42247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
42257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
42268a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
42278a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
42287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
42297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
42309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
42317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
42327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
42337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
42347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
42357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
42367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
42377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
42387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
42397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
42407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
42417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
42427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
42437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
42447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
42457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
42467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42519d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
42529d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
42539d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
425451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Anything that can accept a floating point constant as an operand
425551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // needs to go through here, as the regular ParseExpression is
425651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // integer only.
425751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  //
425851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // This routine still creates a generic Immediate operand, containing
425951222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // a bitcast of the 64-bit floating point value. The various operands
426051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // that accept floats can check whether the value is valid for them
426151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // via the standard is*() predicates.
426251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
42639d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
42649d39036f62674606565217a10db28171b9594bc7Jim Grosbach
42658a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
42668a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
42679d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
42680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
42690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
42700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
42710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
42720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
42730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
42740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
42750e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
42760e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
42770e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
42780e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
42790e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
42800e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
42810e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
42820e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
42830e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
42849d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
42859d39036f62674606565217a10db28171b9594bc7Jim Grosbach
42869d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
42879d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
42889d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
42899d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
42909d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
42919d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
42929d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
4293ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  SMLoc Loc = Tok.getLoc();
42949d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
429551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    APFloat RealVal(APFloat::IEEEsingle, Tok.getString());
42969d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
42979d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
429851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    IntVal ^= (uint64_t)isNegative << 31;
42999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
430051222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
430151222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          MCConstantExpr::Create(IntVal, getContext()),
430251222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach          S, Parser.getTok().getLoc()));
43039d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43049d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
430551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // Also handle plain integers. Instructions which allow floating point
430651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach  // immediates also allow a raw encoded 8-bit value.
43079d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
43089d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
43099d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
43109d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
4311ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach      Error(Loc, "encoded floating point value out of range");
43129d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
43139d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
431451222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    double RealVal = ARM_AM::getFPImmFloat(Val);
431551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Val = APFloat(APFloat::IEEEdouble, RealVal).bitcastToAPInt().getZExtValue();
431651222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach    Operands.push_back(ARMOperand::CreateImm(
431751222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        MCConstantExpr::Create(Val, getContext()), S,
431851222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach        Parser.getTok().getLoc()));
43199d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
43209d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
43219d39036f62674606565217a10db28171b9594bc7Jim Grosbach
4322ae69f703d59410fc96f04be3c1afeaa1c17a45ceJim Grosbach  Error(Loc, "invalid floating point immediate");
43239d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
43249d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
432551222d1551383dd7b95ba356b1a5ed89df69e789Jim Grosbach
43269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
43279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
43281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4329fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4330762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4331fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4332fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4333fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4334f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4335f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4336fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4337f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4338f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4339f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4340f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4341f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4342fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4344146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4345146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
434650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
434719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
43481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
434950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
43500d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
435119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
43520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
435319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
435419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
43553cbe43fe69680df772d83947ced97ca445861213Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
43565cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
43575cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
43585cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
43595cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
43605cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
43615cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4362e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4363e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4364e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
436519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4366758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
436767b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
43686284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
436967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4370515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4371515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4372515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4373762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4374515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
437550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4376762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
437750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
437850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
437950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4380a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
43811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4382d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
43831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
43848a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
438563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4386079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4387079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
4388762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4389b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
439063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
4391515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
4392515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
439350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
439463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4395ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach    if (CE) {
4396ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      int32_t Val = CE->getValue();
4397ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      if (isNegative && Val == 0)
4398ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach        ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
439963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4400762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
440150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
440250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
440363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
44049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
44059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
44067597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
44077597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
44087597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
44091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
44109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44127597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
44137597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
44149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
44159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44167597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
44177597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
44189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
44197597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
44209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
44219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4422a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4423a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4424a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
44251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
44267597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
44271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
44287597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
44299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
44318a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
44329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
44339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
44359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
44369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
44379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
44389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
44409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
44417597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
44429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
44437597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
44449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
44459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
44469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
44479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
44489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
44499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
44509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
44519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
44529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
44539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
44549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
44559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
44569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
44579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4458352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4459352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4460352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4461badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
446289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
44631355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
44645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
44655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
446689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
446789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4468352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4469352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4470a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4471352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4472badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4473352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4474352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
44755f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
44765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
44775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
44785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
44795f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
44805f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
44815f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
44826849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
44836849019079794c573b72c1ec55613cb6ba1297a5Jim Grosbach      Mnemonic == "fmuls")
4484352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4485badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
44863f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
44873f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4488ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
448971725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
449004d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
44912f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
44923f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
44933f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
44943f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
44953f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
44963f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
44973f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
44983f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
44993f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
45003f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
45013f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
45023f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
45033f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
45043f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
45053f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
45063f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
45073f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
45083f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
45093f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
45103f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
45113f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
45123f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
45133f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
45143f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
451552925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4516345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4517352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4518352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4519352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
452000f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
45215f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
45225f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
45235f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
452467ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
452548171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
45269c39789c361d4fe2632f28fca74c9ea5fff3dafcJim Grosbach        Mnemonic == "fsts" || Mnemonic == "fcpys" || Mnemonic == "fdivs" ||
45271aa149f5acea364aa8bc9cfc3a167f78eff2e96bJim Grosbach        Mnemonic == "fmuls" || Mnemonic == "fcmps" ||
4528e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4529352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4530352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4531352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4532352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4534a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4539a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4540a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4541a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4542a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4543a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4544a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4545a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4546a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4547a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
454889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
454989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
455089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
455189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
455289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
455389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4554352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4555352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
45563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
45573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
45583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
45593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
45603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4561fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
45621355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4563fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4564eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4565eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
45663443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4567eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4568d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4569eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4570d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
45713443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4572d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4573d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4574eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4575fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4576eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
45773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4578eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4579eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4580eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4581eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4582ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4583ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
45840780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
45852bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
45862bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
45872bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
45884af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
45894af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
45901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
45913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4592fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
45933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4594fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4595fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4596fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
459763b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4598fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4599fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4600badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4601badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4602d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4603d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
460420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
460520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4606d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4607d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4608d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4609d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4610d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4611d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4612d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4613d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4614d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
46158adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4616d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4617d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4618d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4619d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
46203912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
46213912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
46223912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
46233912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
46243912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
46253912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
46263912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
46273912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
462872f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
462920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
463020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
463120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4632f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4633f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4634f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
463572f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
463672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
463772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
463820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
463920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
464020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
464172f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4642f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4643f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
464420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
464520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
464620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4647f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4648f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
464920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
465020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
465120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
465220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
465320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
465420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
465520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
465612a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // check against T3. If the second register is the PC, this is an
465712a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach    // alternate form of ADR, which uses encoding T4, so check for that too.
465820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
465920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
466012a8863828879168ffd634df09f3aa91b0b256eeJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg() != ARM::PC &&
466120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
466220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
466320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
466420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
466520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
466664944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
466720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
466820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
466920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
467020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
467120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
467220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
467320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
467420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
467520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
467664944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
467764944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
467864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
467964944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
468064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
468164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
468264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
468364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
468464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
468564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
468664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
468764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
468864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
468964944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
46901de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
469164944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
469264944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
469364944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
469464944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
469564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
469664944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
469764944f48a1164c02c15ca423a53919682a89074cJim Grosbach
46987f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
46997f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
47007f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
47017f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
47027f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
47037f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
47047f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
47057f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
47067f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
47077f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
47087f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
47097f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
47107f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
47117f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
471264944f48a1164c02c15ca423a53919682a89074cJim Grosbach
471320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4714f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4715f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4716f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4717f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4718f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4719f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4720f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
472172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
472272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
472372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
472472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
47253912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4726d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4727d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4728d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
47297aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
47307aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
47317aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
47327aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
47337aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
47347aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
47357aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
47367aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
47377aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
47387aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
47397aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
47407aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
47417aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
47427aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
47437aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
47447aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
474521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4746badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4747badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4748badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
474921d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
475021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
475121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
475221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
475321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
475421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
475521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
475621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4757a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4758a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4759a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4760a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4761a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4762a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4763a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4764a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4765a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4766badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4767badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4768ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4769badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4770352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4771352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4772a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4773352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
477489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
47751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
477689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4777badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
47780c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
47790c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
47800c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
47810c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
47820c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
47830c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4784ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4785ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
478689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
478789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
478889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
478989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
479089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
479189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4792f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4793f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4794f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4795f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4796f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
479789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
479889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
479989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
480089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
480189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4802f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
480389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
480489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
480589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
480689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
480789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4808f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
480989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
481089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4811ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4812ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
48139717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
48143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
48153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
48163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
48173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
48183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
48193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
48203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
48213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
48221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
48233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
482433c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
482533c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
482633c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
482733c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4828ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
482933c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
483033c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4831c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4832c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4833c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4834c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4835c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4836c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4837c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
483833c16a27370939de39679245c3dff72383c210bdJim Grosbach
48393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4840f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4841f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
48423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4843f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4844f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
48453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
48463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
48473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4848f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4849f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
48503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4851f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4852badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4853345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4856a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4858a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4859a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4860a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4861345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
48625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
48635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
48645747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4865a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4866a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
48677aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
48687aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
48697aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
48707aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
48717aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
48727aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
487381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
487481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
487581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
487681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
48775747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
48785747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
48795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
48805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4881a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
48821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4883cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4884cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4885cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4887a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4888b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4889a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4890a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
48911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4892cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4893cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4894cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4895a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4896a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
489716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4898cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4899186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4900cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4901186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4902cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4903146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
490434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4905ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4906d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4907d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4908d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
490920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
491020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
491120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
491220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
491320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4914ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4915ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
4916ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
4917ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
4918ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4919cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
4920cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
4921cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
492221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
492321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
4924cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
4925cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
4926cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4927cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
4928cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
4929cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
4930857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
4931857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
4932857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
4933857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
4934857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
4935857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
4936857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4937857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4938857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4939857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
4940857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
4941857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
494268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
494368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
494468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
494568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
494668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
494768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
494868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
494968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
495068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
495168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
495268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4953857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
4954857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
4955857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
4956934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
495755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
495855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
4959934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
496055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
496155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
4962934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4963934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4964934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
496555b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
496655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
4967d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
4968d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
4969d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
497055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
4971d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
4972934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
4973934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4974934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
4975934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
4976934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
4977934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
49789898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
4979ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4980ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4981189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
4982aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
4983aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
4984aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
4985aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
4986aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
4987aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
4988aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
4989aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
4990aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
4991aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
4992aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
4993aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
4994aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
4995aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
4996aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
4997aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
4998aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
4999aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
500076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
500176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
500276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
500376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
500476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
500576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
500676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
500776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
500876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
500976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
501076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
5011f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
5012f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
5013f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
5014f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
50151a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5016f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
50171a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
5018f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
5019f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
5020f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5021189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
5022189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
5023189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
5024189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
50251a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
5026f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
5027f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
5028b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
5029b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // being allowed in IT blocks, but not being predicable.  It just always
5030b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
5031b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
5032f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
5033f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
5034f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
5035f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
5036a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
5037f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
5038f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
5039f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
5040f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
5041f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
5042f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
5043f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
5044f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
5045f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
5046f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
5047f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
5048f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
5049f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
5050f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
5051f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
5052f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
5053f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
5054c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
5055f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
5056f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
505751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
505851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
5059f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
5060f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5061189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
50622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
50632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
50642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
5065189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
5066189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5067189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
5068189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5069189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
5070189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5071189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
5072189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5073189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
507414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
507514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
507614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
507714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
507814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
507914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
508014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
508114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
508214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
508353642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
508453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
5085189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
5086189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
5087189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
5088189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
5089189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
509014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
5091189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
5092189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
5093189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5094fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
5095fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
5096fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
5097fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
5098fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
5099fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
5100fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
5101fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
510200c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
5103fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
510493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
510576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
510676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
510776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
510876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
510976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
511093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
511193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
511293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
51137260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
51147260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
51157260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
5116aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
511776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
5118aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
5119aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
512093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
512176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
512293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
512393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
512476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
512576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
5126aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
51277260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
51287260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
51297260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
513093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
513193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
513293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
513376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
513476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
513576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
513676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
513776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
513876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
513976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
51405402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
51415402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
51425402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
51436dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5144aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
51455402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
51465402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5147aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5148aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
51496dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
51506dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
51516dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5152aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
51535402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
51545402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5155aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5156aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
51576dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
51586dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
51591e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
51601e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
51618213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
51621e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
51631e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
51641e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
51651e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5166189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5167189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5168189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5169189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5170189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
51715b484312c66f8d125c072517947538f301c5a805Jim Grosbachstatic unsigned getRealVSTLNOpcode(unsigned Opc, unsigned &Spacing) {
517284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
517384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  default: assert(0 && "unexpected opcode!");
51749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
51758b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
51765b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd8_UPD;
51788b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
51795b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd16_UPD;
51818b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32:
51825b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd32_UPD;
51848b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
51855b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd8_UPD;
51878b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
51885b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd16_UPD;
51908b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32:
51915b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd32_UPD;
51938b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
51945b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd8;
51968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
51975b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
51989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd16;
51998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32:
52005b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd32;
52029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
52048b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
52055b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd8_UPD;
52078b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
52085b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd16_UPD;
52108b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
52115b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd32_UPD;
52138b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
52145b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 2;
52155b484312c66f8d125c072517947538f301c5a805Jim Grosbach    return ARM::VST2LNq16_UPD;
52168b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32:
52175b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 2;
52185b484312c66f8d125c072517947538f301c5a805Jim Grosbach    return ARM::VST2LNq32_UPD;
52195b484312c66f8d125c072517947538f301c5a805Jim Grosbach
52208b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
52215b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd8_UPD;
52238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
52245b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd16_UPD;
52268b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
52275b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd32_UPD;
52298b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
52305b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 2;
52315b484312c66f8d125c072517947538f301c5a805Jim Grosbach    return ARM::VST2LNq16_UPD;
52328b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32:
52335b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 2;
52345b484312c66f8d125c072517947538f301c5a805Jim Grosbach    return ARM::VST2LNq32_UPD;
52355b484312c66f8d125c072517947538f301c5a805Jim Grosbach
52368b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
52375b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd8;
52398b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
52405b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd16;
52428b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
52435b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 1;
52449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd32;
52458b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
52465b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 2;
52475b484312c66f8d125c072517947538f301c5a805Jim Grosbach    return ARM::VST2LNq16;
52488b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32:
52495b484312c66f8d125c072517947538f301c5a805Jim Grosbach    Spacing = 2;
52505b484312c66f8d125c072517947538f301c5a805Jim Grosbach    return ARM::VST2LNq32;
525184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
525284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
525384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
525495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbachstatic unsigned getRealVLDLNOpcode(unsigned Opc, unsigned &Spacing) {
52557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
52567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  default: assert(0 && "unexpected opcode!");
52579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
52588b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
525995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd8_UPD;
52618b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
526295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd16_UPD;
52648b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32:
526595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd32_UPD;
52678b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
526895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd8_UPD;
52708b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
527195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd16_UPD;
52738b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32:
527495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd32_UPD;
52768b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
527795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd8;
52798b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
528095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd16;
52828b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32:
528395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd32;
52859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
52878b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
528895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd8_UPD;
52908b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
529195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd16_UPD;
52938b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
529495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
52959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd32_UPD;
52968b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
529795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
529895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return ARM::VLD2LNq16_UPD;
52998b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32:
530095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 2;
530195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return ARM::VLD2LNq32_UPD;
53028b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
530395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
53049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd8_UPD;
53058b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
530695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
53079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd16_UPD;
53088b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
530995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
53109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd32_UPD;
53118b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
531295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 2;
531395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return ARM::VLD2LNq16_UPD;
53148b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32:
531595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 2;
531695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return ARM::VLD2LNq32_UPD;
53178b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
531895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
53199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd8;
53208b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
532195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
53229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd16;
53238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
532495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 1;
53259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd32;
53268b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
532795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 2;
532895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return ARM::VLD2LNq16;
53298b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32:
533095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    Spacing = 2;
533195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    return ARM::VLD2LNq32;
53323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
53333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  // VLD3LN
53343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
53353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53363a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd8_UPD;
53373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
53383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd16_UPD;
53403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
53413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd32_UPD;
53433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
53443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNq16_UPD;
53463a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32:
53473a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 2;
53483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNq32_UPD;
53493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
53503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd8_UPD;
53523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
53533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd16_UPD;
53553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
53563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd32_UPD;
53583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
53593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 2;
53603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNq16_UPD;
53613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32:
53623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 2;
53633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNq32_UPD;
53643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
53653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd8;
53673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
53683a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd16;
53703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
53713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 1;
53723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNd32;
53733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
53743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 2;
53753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNq16;
53763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32:
53773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Spacing = 2;
53783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return ARM::VLD3LNq32;
53797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
53807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
53817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
538283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5383f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5384f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5385f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
53860b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  // Aliases for alternate PC+imm syntax of LDR instructions.
53870b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRpcrel:
53880b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRpci);
53890b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
53900b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRBpcrel:
53910b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRBpci);
53920b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
53930b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRHpcrel:
53940b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRHpci);
53950b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
53960b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSBpcrel:
53970b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSBpci);
53980b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
53990b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach  case ARM::t2LDRSHpcrel:
54000b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    Inst.setOpcode(ARM::t2LDRSHpci);
54010b4c6738868e11ba06047a406f79489cb1db8c5aJim Grosbach    return true;
54029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
54038b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
54048b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
54058b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_register_Asm_32: {
540684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
540784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
540884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
54095b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
54105b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing));
541184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
541284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
541384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
541484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
541584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
541684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
541784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
541884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
541984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
542084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
542184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
54229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54238b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_8:
54248b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_16:
54258b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_register_Asm_32:
54268b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_16:
54278b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_register_Asm_32: {
54289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
54299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
54309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
54315b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
54325b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing));
54339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
54349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
54359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
54369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
54379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
54385b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
54395b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
54409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
54419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
54429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
54439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
54449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
54459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
54468b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
54478b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
54488b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: {
544984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
545084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
545184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
54525b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
54535b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing));
545484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
545584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
545684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
545784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
545884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
545984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
546084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
546184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
546284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
546384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
546484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
54659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54668b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:
54678b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:
54688b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:
54698b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_16:
54708b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqWB_fixed_Asm_32: {
54719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
54729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
54739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
54745b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
54755b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing));
54769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
54779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
54789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
54799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
54809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
54815b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
54825b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
54839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
54849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
54859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
54869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
54879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
54889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
54898b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_8:
54908b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_16:
54918b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST1LNdAsm_32: {
549284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
549384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
549484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
54955b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
54965b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing));
549784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
549884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
549984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
550084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
550184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
550284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
550384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
550484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
550584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
55069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55078b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_8:
55088b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_16:
55098b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNdAsm_32:
55108b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_16:
55118b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VST2LNqAsm_32: {
55129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
55139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
55155b484312c66f8d125c072517947538f301c5a805Jim Grosbach    unsigned Spacing;
55165b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode(), Spacing));
55179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55189b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55205b484312c66f8d125c072517947538f301c5a805Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55215b484312c66f8d125c072517947538f301c5a805Jim Grosbach                                            Spacing));
55229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
55249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
55259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
55269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
55279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
55289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
55298b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
55308b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
55318b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: {
5532872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5533872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5534872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
553595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
553695fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
5537872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5538872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5539872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5540872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5541872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5542872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5543872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5544872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5545872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5546872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5547872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5548872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
55499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55508b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:
55518b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:
55528b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:
55538b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_16:
55548b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_register_Asm_32: {
55559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
55569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
55579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
555895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
555995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
55609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
556195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
556295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
55639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
556895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
556995fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
55709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
55719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
55729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
55739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
55749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
55759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
55769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
55773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_8:
55783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_16:
55793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_register_Asm_32:
55803a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_16:
55813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_register_Asm_32: {
55823a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
55833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
55843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
55853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
55863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
55873a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
55883a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55893a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
55903a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55913a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
55923a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
55933a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
55943a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
55953a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
55963a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
55973a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
55983a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
55993a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56003a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
56013a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56023a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
56033a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
56043a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
56053a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
56063a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
56073a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
56088b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
56098b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
56108b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: {
5611872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5612872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5613872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
561495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
561595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
5616872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5617872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5618872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5619872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5620872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
5621872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5622872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5623872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
5624872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
5625872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5626872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5627872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
56289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56298b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:
56308b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:
56318b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:
56328b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_16:
56338b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqWB_fixed_Asm_32: {
56349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
56359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
563795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
563895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
56399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
564095fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
564195fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
56429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
564795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
564895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
56499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
56539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
56549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
56559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
56563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_8:
56573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_16:
56583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdWB_fixed_Asm_32:
56593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_16:
56603a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqWB_fixed_Asm_32: {
56613a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
56623a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
56633a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
56643a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
56653a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
56663a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56673a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56683a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
56693a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56703a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
56713a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
56723a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56733a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56743a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
56753a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
56763a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56773a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
56783a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
56793a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
56803a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
56813a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
56823a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
56833a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
56843a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
56853a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
56863a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
56878b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_8:
56888b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_16:
56898b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD1LNdAsm_32: {
56907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
56917636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
56927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
569395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
569495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
56957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
56967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
56977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
56987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
56997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57027636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
57037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
57047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
57059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
57068b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_8:
57078b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_16:
57088b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNdAsm_32:
57098b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_16:
57108b31f95bdde1e3809a1c9fdb6926b1840effcf9cJim Grosbach  case ARM::VLD2LNqAsm_32: {
57119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
57129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
57139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
571495fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    unsigned Spacing;
571595fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
57169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
571795fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
571895fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
57199b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
572295fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
572395fad1c6034cdf8010428e61b71cd196ee1698adJim Grosbach                                            Spacing));
57249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
57289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
57299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
57303a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
57313a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_8:
57323a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_16:
57333a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNdAsm_32:
57343a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_16:
57353a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  case ARM::VLD3LNqAsm_32: {
57363a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    MCInst TmpInst;
57373a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // Shuffle the operands around so the lane index operand is in the
57383a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    // right place.
57393a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    unsigned Spacing;
57403a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode(), Spacing));
57413a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
57423a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57433a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
57443a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57453a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
57463a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
57473a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
57483a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
57493a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57503a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
57513a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg() +
57523a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach                                            Spacing));
57533a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
57543a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57553a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57563a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    Inst = TmpInst;
57573a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach    return true;
57583a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach  }
57593a678af71dec76a7e1474ad85a99b3588516906dJim Grosbach
5760863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
57612cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVsr:
57622cc5cda464e7c936215281934193658cb799c603Jim Grosbach  case ARM::t2MOVSsr: {
57632cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
57642cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // whether we're in an IT block if the register operands are low
57652cc5cda464e7c936215281934193658cb799c603Jim Grosbach    // registers.
57662cc5cda464e7c936215281934193658cb799c603Jim Grosbach    bool isNarrow = false;
57672cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
57682cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
57692cc5cda464e7c936215281934193658cb799c603Jim Grosbach        isARMLowRegister(Inst.getOperand(2).getReg()) &&
57702cc5cda464e7c936215281934193658cb799c603Jim Grosbach        Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() &&
57712cc5cda464e7c936215281934193658cb799c603Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr))
57722cc5cda464e7c936215281934193658cb799c603Jim Grosbach      isNarrow = true;
57732cc5cda464e7c936215281934193658cb799c603Jim Grosbach    MCInst TmpInst;
57742cc5cda464e7c936215281934193658cb799c603Jim Grosbach    unsigned newOpc;
57752cc5cda464e7c936215281934193658cb799c603Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) {
57762cc5cda464e7c936215281934193658cb799c603Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
57772cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break;
57782cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break;
57792cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break;
57802cc5cda464e7c936215281934193658cb799c603Jim Grosbach    case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR   : ARM::t2RORrr; break;
57812cc5cda464e7c936215281934193658cb799c603Jim Grosbach    }
57822cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.setOpcode(newOpc);
57832cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
57842cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (isNarrow)
57852cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
57862cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
57872cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
57882cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
57892cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
57902cc5cda464e7c936215281934193658cb799c603Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
57912cc5cda464e7c936215281934193658cb799c603Jim Grosbach    if (!isNarrow)
57922cc5cda464e7c936215281934193658cb799c603Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
57932cc5cda464e7c936215281934193658cb799c603Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0));
57942cc5cda464e7c936215281934193658cb799c603Jim Grosbach    Inst = TmpInst;
57952cc5cda464e7c936215281934193658cb799c603Jim Grosbach    return true;
57962cc5cda464e7c936215281934193658cb799c603Jim Grosbach  }
5797863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
5798863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
5799863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
5800863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
5801863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
5802863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
5803863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
5804863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
5805863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
5806863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
5807863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
5808863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
5809863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
5810863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
5811863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
5812863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
5813863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
5814863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
5815520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    case ARM_AM::rrx: isNarrow = false; newOpc = ARM::t2RRX; break;
5816863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
5817863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
5818863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (Ammount == 32) Ammount = 0;
5819863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
5820863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
5821863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
5822863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
5823863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
5824863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
5825520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach    if (newOpc != ARM::t2RRX)
5826520dc78d92a47af5e644b09f401d278cb1d5d196Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Ammount));
5827863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
5828863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
5829863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
5830863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
5831863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
5832863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
5833863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
5834863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
5835863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
583623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
583723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
583823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
583923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
584023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
584123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
584223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
584323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
584423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
584523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
584623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
584723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
584823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
584923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
585023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
585123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
585223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
585323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
585423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
585523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
585623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
585723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
585823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
585923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
586023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
5861ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
5862ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
5863ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
5864ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
5865ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
5866ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
5867ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
5868ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
5869ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
5870ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
5871ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
5872ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
5873ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
587448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
5875ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
5876ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
587771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
5878ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
587971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
588071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
5881ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
5882ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
588371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
588471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
588571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
588671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
588783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
588871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
588948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
589048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
589148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
589248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
589348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
589448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
589548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
589648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
589748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
589848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
589948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
590048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
590148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
59020352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
59030352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
59040352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
59050352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
59060352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
59070352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
59080352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
59090352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
59100352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
59110352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
59120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
59130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
59140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
59150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
59160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
59170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
59180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
59190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
59200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
59210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
59220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
59230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
59240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
59250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
59260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
59270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
59280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
59290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
59300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
59310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
59320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
59330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
5934f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
5935f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
5936f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
5937f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
5938f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
5939f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
5940f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
5941f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
5942f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
5943f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
5944f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
5945f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
5946f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
5947f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5948f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
594983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
5950f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
5951f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
5952f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
5953f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
5954f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
5955f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
5956f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
5957f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
5958f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
5959f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
5960f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
5961f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
5962f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
5963f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
5964f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5965f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
5966f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
5967f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
5968da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
5969da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
5970da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
5971da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
5972da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
5973da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
5974da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
5975da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
5976da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
5977da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
5978da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
5979da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
5980da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
5981da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
5982da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
5983da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
5984da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
5985da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
598689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
59870f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
59880f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
59890f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
59900f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
599183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
599289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
599383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
599483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
599589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
5996f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
5997f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
5998f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
5999f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
6000f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
600183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
6002f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
600383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
600483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6005f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
6006927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
6007927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
6008927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
6009927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
6010927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
6011927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
6012927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
6013713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
6014713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
6015927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
6016927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
6017927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
6018927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6019927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
6020927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
6021927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
6022927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
6023927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
6024927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
6025927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
602651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
602751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
602883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
602951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
603083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
603183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
603251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
603351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
603451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
603583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
603651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
603783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
603883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
603951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
6040c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
6041a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
604283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
6043c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
604483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
604583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
6046c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
6047395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
6048395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
604983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
6050395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
605183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
605283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
60533ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
605476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
605576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
605676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
605776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
605876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
605976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
606076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
606176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
606276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
606376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
606476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
606576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
606676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
606776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
606876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
606976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
607076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
607176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
607276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
607376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
607476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
607583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
607676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
607776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
607876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
60798213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
60808213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
60818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
60828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
60838213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
60848213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
60858213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
60868213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
60878213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
60888213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
608983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
60908213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
60918213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
60928213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
60935402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
60945402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
60955402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
60965402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
60975402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
60985402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
609983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
61005402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
61015402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
61025402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
61035402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
61045402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
610583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
61065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
61075402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
61085402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
61095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
611083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
61115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
61125402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
61135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
61145402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
61155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
611683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
61175402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
61181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
61191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
61201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
61211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
61221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
6123c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
6124c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
6125c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
61261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
61271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
61281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
61291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
61301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
61311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
61321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
61331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
61341ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
61351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
61361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
613783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
61381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
61391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
61401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
61411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
61421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
61431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
61441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
61451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
61461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
61471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
61481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
61491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
61501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
61511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
61521ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
61531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
61541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
61551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
61561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
61571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
615883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
61591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
61601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
61611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
6162326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
616350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
616450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
616550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
6166326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
6167326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
6168326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
6169326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
6170326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
6171326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
6172326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
617350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
617450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
617550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
617650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
617750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
617850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
617950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
618050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
6181326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
6182326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
6183326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
6184326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
6185326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
6186326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
6187326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
6188326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
618983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
6190326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
6191326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
6192326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
619304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  case ARM::MOVsi: {
619404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
619504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (SOpc == ARM_AM::rrx) return false;
619604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
619704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      // Shifting by zero is accepted as a vanilla 'MOVr'
619804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      MCInst TmpInst;
619904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.setOpcode(ARM::MOVr);
620004b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
620104b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
620204b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
620304b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
620404b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
620504b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      Inst = TmpInst;
620604b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach      return true;
620704b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    }
620804b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach    return false;
620904b5d93250bef585631a583a85f6733b1bdc8c52Jim Grosbach  }
62108d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ANDrsi:
62118d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ORRrsi:
62128d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::EORrsi:
62138d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::BICrsi:
62148d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::SUBrsi:
62158d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  case ARM::ADDrsi: {
62168d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    unsigned newOpc;
62178d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm());
62188d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (SOpc == ARM_AM::rrx) return false;
62198d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    switch (Inst.getOpcode()) {
622019055cc2712223f6834fc3cf5b547803ba83f066Matt Beaumont-Gay    default: assert(0 && "unexpected opcode!");
62218d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ANDrsi: newOpc = ARM::ANDrr; break;
62228d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ORRrsi: newOpc = ARM::ORRrr; break;
62238d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::EORrsi: newOpc = ARM::EORrr; break;
62248d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::BICrsi: newOpc = ARM::BICrr; break;
62258d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::SUBrsi: newOpc = ARM::SUBrr; break;
62268d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    case ARM::ADDrsi: newOpc = ARM::ADDrr; break;
62278d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
62288d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    // If the shift is by zero, use the non-shifted instruction definition.
62298d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    if (ARM_AM::getSORegOffset(Inst.getOperand(3).getImm()) == 0) {
62308d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      MCInst TmpInst;
62318d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.setOpcode(newOpc);
62328d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
62338d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
62348d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
62358d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
62368d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(5));
62378d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      TmpInst.addOperand(Inst.getOperand(6));
62388d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      Inst = TmpInst;
62398d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach      return true;
62408d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    }
62418d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach    return false;
62428d9550bde95c8d128e7bf62e9e65dec1854e2d1dJim Grosbach  }
624389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
624489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
624589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
624689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
624789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
624889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
624989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
625089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
625189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
6252f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
6253f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
625489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
625589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
625689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
625789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
625889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
625989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
626089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
6261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
6262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
6263f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
6264f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
6265f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
6266f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
6267f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
6268f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
626989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
627089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
6271f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
627283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
6273f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
6274f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
627547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
627647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
627747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
6278194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
62791a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
628047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
628147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
628247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
628347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
628447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
628547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
628647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
628747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
628847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
628947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
629047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
629147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
629247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
629347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
629447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
629547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
6296f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
6297f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
629847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
6299f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
6300f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
6301f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
630247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
6303194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
6304194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
6305194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
6306194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
6307194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
6308194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
6309194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
63104ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
6311194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
6312194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
6313194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
631447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
631547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
631647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
6317fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
6318fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
6319fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
6320fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
6321fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
6322fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
632319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
6324193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
6325193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
632619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
6327e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
6328189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
6329189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
6330a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
6331a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
6332a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
6333a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
6334189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
6335a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
6336189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
6337f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
633883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
633983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
634083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
634183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
634283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
6343f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
6344a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
6345a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
6346a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
6347a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
6348a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
6349fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
6350fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
6351e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
6352e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
6353e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
6354e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
6355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
6356e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
6357e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
6358e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
635916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6360e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
6361e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
6362e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
636316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6364e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
6365e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
6366e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
636747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
6368b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
636988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
637088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
6371f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
6372f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
637347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
637447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
6375194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
6376194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
6377194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
6378194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
6379fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
638016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6381c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
6382fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
6383fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
63841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
6385ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
6386ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
6387ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
63881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
6389515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
63901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
63919a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
63929a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
6393515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
63941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
6395515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
63961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
6397515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
63981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
6399a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
6400a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
6401d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".arch")
6402d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveArch(DirectiveID.getLoc());
6403d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  else if (IDVal == ".eabi_attribute")
6404d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim    return parseDirectiveEabiAttr(DirectiveID.getLoc());
6405ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
6406ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
6407ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
64081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
6409ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
64101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
6411ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6412ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
6413ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
6414ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
6415ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
6416ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
6417aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
6418ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
6419ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
6420ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
642116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6422ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
6423ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
6424ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
6425b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
6426ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
6427ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
6428ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
6429b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6430ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
6431ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
6432ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
64331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
6434515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
64351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
6436515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
6437515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
6438b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
64409a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
64419a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
64429a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
64439a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
64449a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
64459a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
64469a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
64479a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
64489a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
64499a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
64509a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
64519a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
64529a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
64539a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
64549a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
64559a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
6456515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6457515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6458515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
64591355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
6460515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
64611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
64626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
64636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
64646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
6465de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  bool needFuncName = true;
64666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
6467de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Darwin asm has (optionally) function name after .thumb_func direction
64686469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
64696469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
64706469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
6471de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    if (Tok.isNot(AsmToken::EndOfStatement)) {
6472de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
6473de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach        return Error(L, "unexpected token in .thumb_func directive");
6474de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Name = Tok.getIdentifier();
6475de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      Parser.Lex(); // Consume the identifier token.
6476de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach      needFuncName = false;
6477de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    }
64786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
64796469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
6480de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
6481515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
6482de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach
6483de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // Eat the end of statement and any blank lines that follow.
6484de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  while (getLexer().is(AsmToken::EndOfStatement))
6485de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach    Parser.Lex();
6486515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
64876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
6488de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // We really should be checking the next symbol definition even if there's
6489de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  // stuff in between.
6490de4d83943a5206690fbe1e39dd33770f5ab29595Jim Grosbach  if (needFuncName) {
6491d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
64926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
64936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
6494642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
6495642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
6496642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
6497515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6498515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6499515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
65001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
6501515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
65021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
650318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
6504515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
6505515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
650638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
650758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
6508b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
650958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
65109e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
6511515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
6512515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
6513515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6514515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
651518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
6516b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6517515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6518515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
6519515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
6520515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6521515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6522515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
65231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
6524515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
65251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
652618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
6527515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
6528515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
652918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
653058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
6531b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
653258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
6533b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
6534515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
6535515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
6536515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6537515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
653818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
6539b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6540515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
654132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
654298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
6543ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
654498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
654532869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
654698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
6547ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
654898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
6549eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
65502a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
6551515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6552515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6553515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6554a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
6555a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
6556a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
6557a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
6558a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
6559a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
6560a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
6561a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
6562a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
6563a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
6564a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6565a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
6566a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6567a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
6568a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
6569a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
6570a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
6571a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6572a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
6573a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6574a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
6575a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
6576a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
6577a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6578a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
6579a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
6580a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6581a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
6582a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
6583a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
6584a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
6585a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
6586a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
6587a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
6588a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
6589a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
6590a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
6591a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
6592a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6593d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveArch
6594d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .arch token
6595d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveArch(SMLoc L) {
6596d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
6597d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
6598d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
6599d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim/// parseDirectiveEabiAttr
6600d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim///  ::= .eabi_attribute int, int
6601d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kimbool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) {
6602d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim  return true;
6603d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim}
6604d7c9e08b6bcf15655919960e214b9b91677cdde9Jason W Kim
660590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
660690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
66079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
6608ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
660994b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
661094b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
661190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
6612ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
66133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
66140692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
66150692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
66163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
6617