ARMAsmParser.cpp revision eeaf1c1636c664c707fd9ecc96916fd20ddf137a
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);
104515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
10789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
109fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
11016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
111ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
112ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
113ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
115ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
116ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
117ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
11847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
11947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
12047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
121194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
122194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
123194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
124acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
125acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
126acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
12732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
128ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
129ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
13032869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
131acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
132acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
133acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
134ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1380692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1390692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
141a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
14443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
145f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
147f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1489b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1499b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
15043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1518bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1538bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
15443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1558bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
157f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
164c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
165580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
167293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
169251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1709d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
171862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1727636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
173ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
174ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
175a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
176a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
177a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
178a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
179eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
180eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
181ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
182ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
184ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1859ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1869ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
187548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
188548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
190ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1917b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1927b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
2007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
2012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
2022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
20414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
205623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
206623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
20888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
20912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
21012431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
21112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
21212431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
2134334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2144334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
2154334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2164334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
217189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
218189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
22083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
221f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
222d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
223d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
224189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
225ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
22647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
227194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
228f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
229194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
230194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
23147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
23247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
233ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
23494b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
235ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
23632869205052430f45d598fba25ab878d8b29da2dEvan Cheng
237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
238ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
239f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
240f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
241f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
242ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
243ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
247189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
25047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
25147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
255ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
25616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
25716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2583a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
261a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
262146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2699b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_FPImmediate,
27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
277460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
27821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
27921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
282862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
28398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
28621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
28721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
28821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
28921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
29021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
293762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
29424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
295a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
3008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
3018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
302fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
304fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
305fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
31089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
31189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
31489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
31589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
31689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
326a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
331a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
332a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
333a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
334862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
335862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
336862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
337862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
3390aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      bool isDoubleSpaced;
340862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
341862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3428155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
343460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
344460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
345460a90540b045c102012da2492999557e6840526Jim Grosbach
346460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
347cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
348cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
34916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3509d39036f62674606565217a10db28171b9594bc7Jim Grosbach    struct {
3519d39036f62674606565217a10db28171b9594bc7Jim Grosbach      unsigned Val;       // encoded 8-bit representation
3529d39036f62674606565217a10db28171b9594bc7Jim Grosbach    } FPImm;
3539d39036f62674606565217a10db28171b9594bc7Jim Grosbach
3546a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
355a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
356a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
36257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
36357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
364eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                                // n = alignment in bytes (2, 4, 8, 16, or 32)
3657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
366e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
370f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
371f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
372f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
376580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
378580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
379e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
384af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
38592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
38692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
38792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
38892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
389af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
393293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
394293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
395293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
396293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
397a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
39816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
399146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
400146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
403762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
405762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4088462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
41089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
41189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
41221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
414762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
41621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
417762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
418762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
42224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4238d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
424862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
42598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4267636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
427862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
428862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
42921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
431fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
432fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4339b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
437762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
438762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_FPImmediate:
4409d39036f62674606565217a10db28171b9594bc7Jim Grosbach      FPImm = o.FPImm;
4419d39036f62674606565217a10db28171b9594bc7Jim Grosbach      break;
44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
443706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
444706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
446e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
447762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
452584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
453584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
455a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
461af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
46321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
464af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
46592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
46921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
470293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
471293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
472460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
473460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
474460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
476762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
478762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
479762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
480762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
481762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
482a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4838462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
48421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
488fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
48921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
490fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
491fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
492fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
49421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
497a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
498a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
5007729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
502a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5035fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
50421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
50521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
50624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
509cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
51021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Immediate && "Invalid access!");
511cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
512cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
513cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
5149d39036f62674606565217a10db28171b9594bc7Jim Grosbach  unsigned getFPImm() const {
51521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_FPImmediate && "Invalid access!");
5169d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return FPImm.Val;
5179d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
5189d39036f62674606565217a10db28171b9594bc7Jim Grosbach
519460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
520460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
521460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
522460a90540b045c102012da2492999557e6840526Jim Grosbach  }
523460a90540b045c102012da2492999557e6840526Jim Grosbach
524706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
52521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
526706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
527706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
528706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
53021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
532a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
534584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
536584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
537584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
538584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
54021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
54221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
54421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
54521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
54621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
54721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isFPImm() const { return Kind == k_FPImmediate; }
548a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
54921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
550a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
551a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
552a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
553a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
554a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
555a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
55672f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
55721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
55872f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
55972f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
56072f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
56172f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
56272f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
56372f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
56472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
56521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
56672f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
56772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
56872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
56972f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
57072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
57172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
57321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
5756b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5776b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
580587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
581587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (Kind != k_Immediate)
582587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach      return false;
583587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
584587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
585587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
586587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
587587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
588587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (Kind != k_Immediate)
590587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach      return false;
591587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
592587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
593587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
594587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
595587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
59683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
59721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
59883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
59983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
60283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
60521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
60783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
61183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6127c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
61321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
6147c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      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 {
621730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (Kind != k_Immediate)
622730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach      return false;
623730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
624730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
625730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
626730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
627730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6283b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
6293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6353b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6393b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6423b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6463b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6473b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6483b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6493b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6503b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6513b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
6536b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6566b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6606b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6636b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6676b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      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 <= 32;
6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6766b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6786b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6796b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6806b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6816b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6826b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
6836b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6883b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
6913b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6953b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6973b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6983b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
6993b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
7003b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
7013b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
7023b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
7033b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7043b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
7053b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7063b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
7073b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
708f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
70921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
710f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
711f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
712f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
713f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
714f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
715f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
71721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
7184a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
7194a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
724ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
725ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Kind != k_Immediate)
726ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      return false;
727ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
728ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
729ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
730ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
731ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
732fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
73321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
734fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
735fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
736fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
737fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
738fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
739fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
740ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
74121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
742ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
743ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
744ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
745ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
746ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
747ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
748ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
749ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
750ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
75121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
752ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
753ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
754ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
755ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
756ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
757ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
75870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
75921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
76070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
76170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
76270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
76370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
76470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
76570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
76721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
769f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
77521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
776f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
777f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
778f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
779f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
780f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
781f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7826bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
78321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
7846bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
7856bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7866bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
7876bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
7886bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
7896bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
790e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
791e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (Kind != k_Immediate)
792e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach      return false;
793e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
794e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
795e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
796e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
797e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
7983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
7993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (Kind != k_Immediate)
8003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach      return false;
8013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8043bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getSOImmVal(-Value) != -1;
8053bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
8066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
80721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
8086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
8096b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8106b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
8116b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
8126b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
8136b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
81489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
81589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (Kind != k_Immediate)
81689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach      return false;
81789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
81889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
81989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
82089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
82189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
8223bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
8233bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (Kind != k_Immediate)
8243bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach      return false;
8253bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8263bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8273bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8283bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getT2SOImmVal(-Value) != -1;
8293bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
830c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
83121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
832c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
833c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
834c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
835c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
836c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
837c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
83821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
83921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
84021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
84121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
84221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
84321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
84421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
84521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
84621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
84721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
84821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
84921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
85021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
851f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
852430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
853f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
85457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
855f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
856ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
85857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
85957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
86057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
86157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
86257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
863ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
86557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
867e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
869e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
870e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
873039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
87421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
875039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
876039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
877039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
878039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
879039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
880039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
881039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
8822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
88357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
885e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
887e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
889e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
890e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
89421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
89621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
8972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
8992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
9012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
902251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
903251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
9042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
9057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
906681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
907681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
908681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
909681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
910681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
91157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
913e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
915e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
916e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9170da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
918681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
921e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9237f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9257f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
927e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
92957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9307f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9317f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9327f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
93457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
935ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
936ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
937ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
938ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
93957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
94057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
941ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
942ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
943e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
944ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
945e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
946ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
947ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
948ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
952e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
95357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
95487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
955e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
956e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
95760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
95860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
959e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
96160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
96260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
963e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
964e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
965ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
966ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
96738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
968e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
97038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
97138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
972e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
973e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
97438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
97538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
97648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
977e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
97948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
98048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
981e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
982e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
98348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
98448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
985ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
98657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
98757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
988ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
989ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
990e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
991e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
992ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
993505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
99557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
996a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
997a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
998e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
999e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1000a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
1001a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
100357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1004b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
1005b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
1006e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1007e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1008b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1009b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
101157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1012f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1014e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1015e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10164d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1017f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1018f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
101957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1020f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1021f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1022e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1023e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1024f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1025f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1026a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
102757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1028a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1029a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1030df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1031e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1032df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1033a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
103557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1036a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1037a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1038e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1039e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1040a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1041a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
104309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
104409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
104509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
104621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
104709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
104809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
104957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1050ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1052e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1053e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10540da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
105721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
10587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
10597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1060ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
10617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
106263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1063ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
10652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Kind != k_Immediate)
10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      return false;
10672bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10682bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
10692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
10702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
10712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
10722bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
10737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
107421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
107521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
10763483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10770e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
10780aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isSingleSpacedVectorList() const {
10790aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && !VectorList.isDoubleSpaced;
10800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
10810aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  bool isDoubleSpacedVectorList() const {
10820aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return Kind == k_VectorList && VectorList.isDoubleSpaced;
10830aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach  }
1084862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
10850aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1086862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1087862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1088862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1089280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  bool isVecListTwoD() const {
10900aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1091280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    return VectorList.Count == 2;
1092280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
1093280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
1094cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
10950aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1096cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1097cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1098cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1099b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
11000aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isSingleSpacedVectorList()) return false;
1101b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1102b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1103b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
11044661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  bool isVecListTwoQ() const {
11050aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!isDoubleSpacedVectorList()) return false;
11060aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    return VectorList.Count == 2;
11074661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  }
11084661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach
110998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
111098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Kind != k_VectorListAllLanes) return false;
111198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
111298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
111398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
111413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  bool isVecListTwoDAllLanes() const {
111513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    if (Kind != k_VectorListAllLanes) return false;
111613af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
111713af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
111813af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11197636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
11207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (Kind != k_VectorListIndexed) return false;
11217636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
11227636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
11237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1124799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDHWordIndexed() const {
1125799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    if (Kind != k_VectorListIndexed) return false;
1126799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 3;
1127799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1128799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1129799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListOneDWordIndexed() const {
1130799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    if (Kind != k_VectorListIndexed) return false;
1131799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 1;
1132799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1133799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
11349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  bool isVecListTwoDByteIndexed() const {
11359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    if (Kind != k_VectorListIndexed) return false;
11369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 7;
11379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
11389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
1139799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDHWordIndexed() const {
1140799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    if (Kind != k_VectorListIndexed) return false;
1141799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 3;
1142799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1143799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1144799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  bool isVecListTwoDWordIndexed() const {
1145799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    if (Kind != k_VectorListIndexed) return false;
1146799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach    return VectorList.Count == 2 && VectorList.LaneIndex <= 1;
1147799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach  }
1148799ca9d1b7cfa8910ac27f8de4929bfbd278114dJim Grosbach
1149460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1150460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1151460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1152460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1153460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1154460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1155460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1156460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1157460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1158460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1159460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1160460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1161460a90540b045c102012da2492999557e6840526Jim Grosbach
11620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
11630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (Kind != k_Immediate)
11640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach      return false;
11650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
11670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
11680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
11690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
11700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
11710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
11720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1173460a90540b045c102012da2492999557e6840526Jim Grosbach
1174ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
1175ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Kind != k_Immediate)
1176ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      return false;
1177ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1178ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1179ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1180ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1181ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1182ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1183ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1184ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
11856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
11866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Kind != k_Immediate)
11876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      return false;
11886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
11906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
11916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
11926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
11936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
11946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
11956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
11966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
11976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
11986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
11996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
12006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Kind != k_Immediate)
12016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      return false;
12026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
12046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
12056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
12066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
12076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
12086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
12096248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
12106248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
12116248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
12126248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
12136248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
12146248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
12156248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1216f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
1217f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (Kind != k_Immediate)
1218f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      return false;
1219f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1220f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1221f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1222f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1223f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1224f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1225f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1226f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1227f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1228f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
12293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
123014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
123114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
123214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
123314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
12343483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
12353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
12363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
12373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
12383483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
12398462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1240345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
12418462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
124204f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
124304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
12448462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
12458462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1246fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1247fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1248fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1249fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1250fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
12519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
12529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
12539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
12549b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
12559b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
12569b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
12579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
12589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
12599b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
12609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
126189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
126289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
126389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
126489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
126589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
126689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
126789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
126889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
126989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
127089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1271d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1272d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1273d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1274d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1275d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1276a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1280a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1281af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1283430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1284430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1285af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1286af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1287e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1288af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1289e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1290e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1291af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1292152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1293430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1294430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1295af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
129692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1297af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
129892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
129992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1300580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
13010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1302580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1303580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
13040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
13050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
130687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
13077729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
13085fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
13095fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
13107729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
13117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
131287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
131387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
13140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
13150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
13160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
13170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
13180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
13190f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
13200f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
13210f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
13227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
13237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
13257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
13267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
13277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1328293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1329293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1330293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1331293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1332293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1333293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1334293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1335293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1336293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1337293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1338293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
13393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
13406b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13416b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
13426b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
13436b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
13449d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
13459d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13469d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getFPImm()));
13479d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
13489d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1349a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1350a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1351a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1352a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1353a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1354a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1355a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1356a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
135772f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
135872f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
135972f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
136072f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
136172f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
136272f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
136372f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
136472f39f8436848885176943b0ba985a7171145423Jim Grosbach
136572f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
136672f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
136772f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
136872f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
136972f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
137072f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
137172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
137272f39f8436848885176943b0ba985a7171145423Jim Grosbach
1373f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1374f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1375f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1376f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1377f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1378f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1379f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1380f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
13814a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
13824a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13834a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
13844a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
13854a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13864a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
13874a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
13884a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
138970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
139070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
139170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
139270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
139370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
139470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
139570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1396ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1397ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1398f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1399f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1400f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1401f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1402f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1403f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1404f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1405f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1406f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
140789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
140889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
140989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
141089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
141189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
141289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
141389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
141489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
14153bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
14163bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14173bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
14183bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
14193bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14203bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
14213bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
14223bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1423e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1424e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1425e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1426e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1427e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1428e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1429e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1430e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
14313bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
14323bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14333bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
14343bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
14353bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14363bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
14373bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
14383bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1439706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1440706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1441706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1442706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1443706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
14447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
14457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1446e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1447505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1448505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
144957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
145057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
145157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
145257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
145357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
145457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
14557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
14567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1457e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1458e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
14597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
14607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
14617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
14627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
14637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
14647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
14657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
14667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1467e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1468e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1469ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1470e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1471e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
14727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1473ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1474ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1475039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1476039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1477039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1478039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1479039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1480039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1481039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1482039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1483039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1484039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1485039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1486039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1487039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1488039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
14892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
14902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1491e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1492e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
14932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
14942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
14952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
14962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
14972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
14982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
14992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
15002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1501e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
15022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1503e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1504e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
15052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
15072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
15082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
15092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
151021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
15112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
15122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
15132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
15142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1515251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
15162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
15172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
15182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
15192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
15202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
15212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
15222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
15232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
15242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1525251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
15262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
15272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
15292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
15307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
15317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1532681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1533681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1534681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1535681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1536681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1537681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1538681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1539681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1540681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
15417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1542e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
15437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
15447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
15457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
15467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
15477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1548e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
15497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
15517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1552a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1553a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1554e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1555e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1556a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1557a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1558a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1559b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1560b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1561b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1562e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1563e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1564b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1565b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1566b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
15677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
15687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1569e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1570e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
15717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1572ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1573ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1574f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1575f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1576f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1577f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1578a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1579f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1580a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1581a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1582a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1583a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1584a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
158521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
1586a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1587a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1588a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1589a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1590a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1591a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1592e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1593e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1594a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1595a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1596a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
15977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
15987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
159909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
160021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
160109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
160209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
160309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
160409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
160509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
160609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1607e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1608e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
16097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
161192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
16127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
16137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1614e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1615e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16167f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
16177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
16187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
16197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1620e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1621e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16227f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
16237f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
16247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
16257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1626430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1627430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1628430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1629e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1630e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
16317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
16327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1633d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1634ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1635ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1636e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1637e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1638e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1639ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1640ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
16417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
16427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1643e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1644e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
164514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
16463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
164760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
164860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1649e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1650e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
165160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
165248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
165348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
165438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
165538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1656e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1657e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
165838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
165938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
166038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
166148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
166248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1663e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1664e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
166548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
166660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
166760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1668ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1669ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1670e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1671e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1672ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1673ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1674ecd858968384be029574d845eb098d357049e02eJim Grosbach
16757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
16767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
16777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
16797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
16807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
168163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
16827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
16837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1684f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1685ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
16862bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
16872bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16882bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16892bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
16902bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
16912bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
16922bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
16932bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
16942bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
16952bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
16962bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
16972bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
16987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
16997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
17007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1701f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1702f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1703f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1704f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1705f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1706f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1707f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1708f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1709f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1710f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1711f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1712f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1713ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1714ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1715584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1716584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1717584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1718584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1719584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1720a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1721a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1722a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1723a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1724a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
17256029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1726862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1727862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1728862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1729862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
17307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
17317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
17327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
17337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
17347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
17357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1736460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1737460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1738460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1739460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1740460a90540b045c102012da2492999557e6840526Jim Grosbach
1741460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1742460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1743460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1744460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1745460a90540b045c102012da2492999557e6840526Jim Grosbach
1746460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1747460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1748460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1749460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1750460a90540b045c102012da2492999557e6840526Jim Grosbach
17510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
17520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
17540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
17550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
17570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
17580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1759ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1760ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1761ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1762ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1763ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1764ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1765ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1766ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1767ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1768ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1769ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1770ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
17716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
17726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
17746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
17766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
17776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
17786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
17796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
17806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
17816248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
17826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
17836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
17846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
17856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
17866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
17886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
17906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
17916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
17926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
17936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
17946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
17956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
17966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
17976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
17986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1799f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1800f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1801f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1802f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1803f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1804f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1805f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1806f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1807f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1808f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1809f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1810f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1811b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1812b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
181389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
181421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
181589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
181689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
181789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
181889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
181989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
182089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
18213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
182221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1823345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1824345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1825345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
18263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1827345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1828345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1829fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
183021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1831fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1832fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1833fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1834fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1835fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1836fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1837fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
183821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
1839fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1840fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1841fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1842fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1843fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1844fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
18459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
18469b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
18479b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
18489b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
18499b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
18509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
18519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
18529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
1853d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
185421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
1855d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1856d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1857d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1858d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1859d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1860d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
18613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
186221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
1863762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1864762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1865762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1866762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
18673a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1868a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1869a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
187050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
187121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
1872762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1873762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1874762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
18753a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1876a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1877a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1878e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1879e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1880e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1881e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1882e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
188321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
1884af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1885af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1886af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1887af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1888e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1889e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1890e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1891e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1892e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
189392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
189492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
189592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
189692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
189721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
1898af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1899af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1900af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
190192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
190292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
190392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
190492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
190592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1906580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
19070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
190821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
1909580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1910580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
19110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
19120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
19130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
19140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
19150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
19167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
191721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
19187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
19197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
19207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
19217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
19227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
19237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1924293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1925293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
192621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
1927293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1928293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1929293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1930293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1931293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1932293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1933293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
19347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
19355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1936cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
193721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
19380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1939d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
194021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
1941d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
1942275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
194321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
19440f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
19450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
19465fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
19477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
194824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1949cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1950cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1951cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
19528d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
19538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
19548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
1955862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
19560aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                      bool isDoubleSpaced, SMLoc S, SMLoc E) {
1957862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
1958862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
1959862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
19600aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Op->VectorList.isDoubleSpaced = isDoubleSpaced;
1961862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
1962862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
1963862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
1964862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1965862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
196698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
196798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
196898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
196998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
197098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
197198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
197298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
197398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
197498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
197598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
19767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
19777636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                             unsigned Index, SMLoc S, SMLoc E) {
19787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
19797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
19807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
19817636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
19827636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
19837636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
19847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
19857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
19867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1987460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1988460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
1989460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
1990460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
1991460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
1992460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
1993460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
1994460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1995460a90540b045c102012da2492999557e6840526Jim Grosbach
19963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
199721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
1998762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1999762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2000762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
20013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2002cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
2003cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
20049d39036f62674606565217a10db28171b9594bc7Jim Grosbach  static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
200521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_FPImmediate);
20069d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->FPImm.Val = Val;
20079d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->StartLoc = S;
20089d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->EndLoc = S;
20099d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return Op;
20109d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
20119d39036f62674606565217a10db28171b9594bc7Jim Grosbach
20127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
20137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
20147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
20157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
20160d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
201757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
20187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
20193a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
202021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
2021e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
2022e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
2023e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
2024e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
2025e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
202657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
2027e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
20287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
20297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
20307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
20317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
203216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2033f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
2034f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
2035f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
20367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
203721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
20387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2039f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2040f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2041f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2042762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2043762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
20443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2045a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2046706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2047706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
204821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2049706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2050706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2051706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2052706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2053706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2055a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
205621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2057a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2058a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2059a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2060a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2061a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2062584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2063584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
206421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2065584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2066584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2067584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2068584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2070a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2071a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2072a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2073a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2074b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2075fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
207621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_FPImmediate:
20779d39036f62674606565217a10db28171b9594bc7Jim Grosbach    OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm())
20789d39036f62674606565217a10db28171b9594bc7Jim Grosbach       << ") >";
20799d39036f62674606565217a10db28171b9594bc7Jim Grosbach    break;
208021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
20816a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2082fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
208321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2084d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2085d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
208621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
20871a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    static const char *MaskStr[] = {
20881a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
20891a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
20901a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
209189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
209289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
209389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
209489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
209521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2096fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2097fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
209821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2099fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2100fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
21019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
21029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
21039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
210421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2105584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2106584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
210721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2108fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2109fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
211021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2111706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2112706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
211321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
21146ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2115e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
21166ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2117fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
211821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2119f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2120f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2121f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2122f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2123f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2124f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
21257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
212621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2127a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2128a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2129a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2130a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2131a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2132a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2133a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2134a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
213521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
213650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2137fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
213821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2139580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2140580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2141e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
214221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
214392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2144efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2145efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2146efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
21470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
214821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
214992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2150efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2151efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2152efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
215392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
215421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
21557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
21567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
215721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2159293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2160293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
216121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
216221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
216321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
21648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
21658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
21665fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
21675fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
21687729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
21697729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
21707729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
21718d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
21728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
21738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
21748d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
21758d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2176862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2177862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2178862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2179862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
218098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
218198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
218298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
218398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
21847636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
21857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
21867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
21877636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
218821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2189fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2190fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2191460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2192460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2193460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2194fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2195fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
21963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
21973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
21983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
21993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
22003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
22013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
22023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
22033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
220469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
220569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
2206a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  StartLoc = Parser.getTok().getLoc();
22071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2208a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  EndLoc = Parser.getTok().getLoc();
2209bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2210bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2211bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2212bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
22139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2214e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2215e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
22163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
22171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
221818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
22197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2220d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2221590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
22220c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
22230c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
22240c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
22250c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
22260c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
22270c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
22280c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
222940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
223040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
223140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
223240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
223340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
223440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
223540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
223640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
223740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
223840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
223940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
224040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
224140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
224240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
224340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
224440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
22450c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
22460c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
2247a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (!RegNum) {
2248a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // Check for aliases registered via .req.
2249a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    StringMap<unsigned>::const_iterator Entry =
2250a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      RegisterReqs.find(Tok.getIdentifier());
2251a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // If no match, return failure.
2252a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    if (Entry == RegisterReqs.end())
2253a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      return -1;
2254a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.Lex(); // Eat identifier token.
2255a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Entry->getValue();
2256a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
225769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2258b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2259460a90540b045c102012da2492999557e6840526Jim Grosbach
2260e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2261e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2262d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
226319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
226419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
226519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
226619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
226719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
22680d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
22690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
22710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
22720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
22730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2274590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
22750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2276af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
22770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
22780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
22790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
22800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
22810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
22820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
22830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
22840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
228519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
22860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2287e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2288e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2289e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2290e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2291e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2292eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2293e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2294e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2295e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2296e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2297e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2298e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2299e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2300e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2301e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2302e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2303e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2304e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
23058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
23068a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2307e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2308e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2309e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
231019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
231119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
231219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
231319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2314e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2315e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
231619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
231719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
231819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
231919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2320e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2321e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2322e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2323e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2324e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2325e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2326e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
232719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
232819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2329e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2330e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
23311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2332e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
233319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
233419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
233519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
233619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
233719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
233819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2339e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
234019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
234119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2342e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2343e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
234492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
234592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2346af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
23470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
234892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
234992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
235092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
23510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
235219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
23530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
23540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
23550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
235650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
235750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
235850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2359e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2360e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2361e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
236250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
23631355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2364e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
23651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2366e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
236750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2368d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
236950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2370a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2371e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2372e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
237350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
237450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2375e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2376460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2377460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2378460a90540b045c102012da2492999557e6840526Jim Grosbach
2379460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2380460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2381460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2382460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2383460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2384460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2385460a90540b045c102012da2492999557e6840526Jim Grosbach
2386460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2387460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
2388460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2389460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2390460a90540b045c102012da2492999557e6840526Jim Grosbach    if (!MCE) {
2391460a90540b045c102012da2492999557e6840526Jim Grosbach      TokError("immediate value expected for vector index");
2392460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2393460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2394460a90540b045c102012da2492999557e6840526Jim Grosbach
2395460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2396460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2397460a90540b045c102012da2492999557e6840526Jim Grosbach      Error(E, "']' expected");
2398460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2399460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2400460a90540b045c102012da2492999557e6840526Jim Grosbach
2401460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2402460a90540b045c102012da2492999557e6840526Jim Grosbach
2403460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2404460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2405460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
240699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
240799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
240850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2409a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2410a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2412fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2413fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2414fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2415e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2416e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2417e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
2418e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
2419e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2420fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2421e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2422e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2423e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2424e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2425e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2426e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2427e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2428e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2429e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2430e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2431e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2432e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2433e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2434e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2435e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
2436e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2437fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2438e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2439e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2440e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2441e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2442e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2443e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2444e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2445e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2446e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2447e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2448e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
2449e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2450e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2451e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
2452e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2453e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
245489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
245589df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
245689df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
245789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
245889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
245989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
246089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
246189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
246289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
246389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
246489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
246589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
246689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
246789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
246889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
246989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
247089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
247189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
247289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
247389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
247489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
247589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
247689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
247789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
247889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
247989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
248089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
248189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
248289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
248389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
248489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
248589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
248689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
248789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
248889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
248943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2490fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2491fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2492f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
249343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2494e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2495e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2496c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2497c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2498e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2499fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2500e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2501f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2502e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2503e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2504fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2505f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2506fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2507fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
250843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2509fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2510fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2511f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
251243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2513fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2514fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2515c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2516c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2517fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2518fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2519fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2520f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2521fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2522fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2523fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2524f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2525e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2526e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
25279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
25289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
25299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
25309b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
25319b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
25329b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
25339b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
25349b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
25359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
25369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
25379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
25389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
25399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
25409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
25419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
25429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
25439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
25449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
25459b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
25469b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
25479b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
25489b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
25499b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
25509b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
25519b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
25529b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
25539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
25549b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
25559b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
25569b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
25579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
25589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
25599b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
25609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2561d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2562d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2563d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2564d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2565d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2566d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2567d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2568d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2569d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2570d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2571d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
2572d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2573d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2574d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2575d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2576d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2577d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2578d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2579d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2580d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2581d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2582d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2583ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2584ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2585ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2586ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2587ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2588ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2589ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2590ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2591ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2592ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2593ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2594ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2595ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
259625e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2597ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2598ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2599ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2600ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2601ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2602ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2603ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2604ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2605ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2606d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
260750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
26081355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
260918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2610a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2611e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2612d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2613d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
261416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2615d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2616d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2617d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2618d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2619d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2620d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2621ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2622ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2623ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2624ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2625ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2626ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2627ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2628ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2629ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2630ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
26311a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2632d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2633d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2634d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2635d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2636d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2637d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2638d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2639d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2640e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2641ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2642d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2643d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2644d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2645d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2646d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2647d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2648d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2649d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2650e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2651d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2652d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2653d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2654d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2655ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2656ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2657ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2658d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2659d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2660d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2661d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2662d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2663d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2664d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2665d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2666d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2667d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2668d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2669d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2670d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2671d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2672d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2673d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2674d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2675d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2676d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2677d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2678d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2679a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2680d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2681d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
26822d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2683ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2684ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2685ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2686ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2687ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2688ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2689d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2690d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2691d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2692d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2693a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg))
2694d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2695a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) {
2696a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2697a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2698a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2699a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2700d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2701d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2702d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2703d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2704d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2705d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2706d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2707ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2708ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2709d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2710d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2711d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2712d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2713d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2714d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2715e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
271627debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // Push the register list operand.
271750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
271827debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
271927debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  // The ARM system instruction variants for LDM/STM have a '^' token here.
272027debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  if (Parser.getTok().is(AsmToken::Caret)) {
272127debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("^",Parser.getTok().getLoc()));
272227debd60a152d39e421c57bce511f16d8439a670Jim Grosbach    Parser.Lex(); // Eat '^' token.
272327debd60a152d39e421c57bce511f16d8439a670Jim Grosbach  }
272427debd60a152d39e421c57bce511f16d8439a670Jim Grosbach
272550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2726d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2727d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
272898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
272998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
27307636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
27317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
273298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
273398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
273498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
273598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
273698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
273798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
273898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
273998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
27407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (Parser.getTok().is(AsmToken::Integer)) {
27417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      int64_t Val = Parser.getTok().getIntVal();
27427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      // Make this range check context sensitive for .8, .16, .32.
27437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (Val < 0 && Val > 7)
27447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Error(Parser.getTok().getLoc(), "lane index out of range");
27457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      Index = Val;
27467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      LaneKind = IndexedLane;
27477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      Parser.Lex(); // Eat the token;
27487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (Parser.getTok().isNot(AsmToken::RBrac))
27497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Error(Parser.getTok().getLoc(), "']' expected");
27507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      Parser.Lex(); // Eat the ']'.
27517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      return MatchOperand_Success;
27527636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
27537636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Error(Parser.getTok().getLoc(), "lane index must be empty or an integer");
275498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
275598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
275698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
275798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
275898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
275998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
2760862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2761862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2762862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
276398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
27647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
27655c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
27665c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
27675c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
27685c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
27695c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
27705c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
27715c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
27725c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
27735c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
27745c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
27757636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
277698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
277798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
277898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
277998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      default:
278098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        assert(0 && "unexpected lane kind!");
278198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
278298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
27830aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, false, S, E));
278498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
278598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
278698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
278798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, S, E));
278898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
27897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
27907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
27917636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                                               LaneIndex, S,E));
27927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
279398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
27945c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
27955c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
27965c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
27975c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
27987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
279998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
280098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
280198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
280298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      default:
280398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        assert(0 && "unexpected lane kind!");
280498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
280598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
28060aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, false, S, E));
280798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
280898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
280998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
281098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, S, E));
281198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
28127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
28137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
28147636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                                               LaneIndex, S,E));
28157636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
281698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
28175c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
28185c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
28195c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
28205c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
28215c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
28225c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
28235c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
2824862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
2825862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2826862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
2827862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
2828862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2829862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
2830862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
2831862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
2832862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2833862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2834862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
2835276ed0344c05822617934fa4a6a9920d864193a5Jim Grosbach  int Spacing = 0;
2836c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
2837c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
2838c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
2839c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2840c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
28410aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Spacing = 1; // double-spacing requires explicit D registers, otherwise
28420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                 // it's ambiguous with four-register single spaced.
2843c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
2844c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
2845c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
28467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
284798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
2848c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
2849e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2850e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2851e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
28520aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
28530aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
28540aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
28550aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(Parser.getTok().getLoc(),
28560aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "sequential registers in double spaced list");
28570aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
28580aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
2859e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2860e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2861e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
2862e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
2863e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
2864e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2865e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
2866e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2867e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2868e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2869e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
2870e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
2871e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
2872e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
2873e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
2874e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
2875e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
2876e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2877e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
2878e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
2879e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
2880e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
2881e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2882e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
288398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
288498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
28857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
28867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
288798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
28887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
288998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
289098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
289198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
289298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
2893e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
2894e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
2895e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
2896e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
2897e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
2898e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
2899862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
2900862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
2901862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
2902862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
2903862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
2904862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
2905862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
2906862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
2907c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
2908862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2909862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
2910c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
2911c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
2912c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
2913c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
29140aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      if (!Spacing)
29150aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Spacing = 1; // Register range implies a single spaced list.
29160aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      else if (Spacing == 2) {
29170aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        Error(RegLoc,
29180aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach              "invalid register in double-spaced list (must be 'D' register')");
29190aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach        return MatchOperand_ParseFail;
29200aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      }
2921c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
2922c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
2923c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
2924c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
2925c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
2926c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
2927c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
292898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
292998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
29307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
293198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
29327636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
293398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
29347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
293598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
293698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
293798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
2938c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
2939c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
29400aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Normal D register.
29410aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Figure out the register spacing (single or double) of the list if
29420aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // we don't know it already.
29430aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (!Spacing)
29440aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Spacing = 1 + (Reg == OldReg + 2);
29450aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach
29460aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    // Just check that it's contiguous and keep going.
29470aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Reg != OldReg + Spacing) {
2948862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
2949862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
2950862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
2951862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
295298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
295398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
29547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
295598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
29567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
295798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
29587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
295998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
296098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
296198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
29620aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    if (Spacing == 2 && LaneKind != NoLanes) {
29630aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      Error(EndLoc,
29640aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach            "lane index specfier invalid in double spaced register list");
29650aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach      return MatchOperand_ParseFail;
29660aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    }
2967862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2968862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2969862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2970862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
2971862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
2972862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2973862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2974862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
2975862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
297698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
297798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  default:
297898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    assert(0 && "unexpected lane kind in register list.");
297998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
29800aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count,
29810aaf4cd9b34454eb381e1694f520504779c6b7f8Jim Grosbach                                                    (Spacing == 2), S, E));
298298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
298398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
298498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
298598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
298698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
29877636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
29887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
29897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                                           LaneIndex, S, E));
29907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
299198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
2992862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
2993862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
2994862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
299543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
2996f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
299743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2998706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2999706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3000706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3001706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
3002706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3003706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
3004706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
3005706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
3006032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
3007706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
3008032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
3009706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
3010706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
3011032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
3012706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
3013032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
3014706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
3015706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
3016706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
3017706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3018706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
3019f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
3020706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
3021706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3022706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
3023f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
3024706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
3025706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
302643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
3027a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
302843904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3029a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3030a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3031a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3032a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
3033a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
30342dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
30352dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
3036a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
30372dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
30382dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
30392dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
30402dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
30412dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
30422dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
30432dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
30442dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
30452dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
30462dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
30472dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
30482dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
30492dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
30502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
30512dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
3052a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3053a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3055a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
3056a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
3057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
3058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
305943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
3060584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
306143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3062584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
3063584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
3064584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
3065584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
3066584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3067acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
3068acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
3069acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
3070acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
3071acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
3072acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
3073acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
3074acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
3075acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
3076acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
3077acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
3078acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
3079acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
3080acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
3081acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
3082acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
3083acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
3084acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
3085acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3086acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3087acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3088acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3089acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
3090acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3091acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3092acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3093acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3094acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3095acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3096acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3097acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3098584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3099584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3100584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3101590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3102584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3103584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3104584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3105584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3106584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3107584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3108584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3109584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3110584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3111584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3112b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3113584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3114584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3115584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
31174b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3118584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3119584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3120584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3121bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
31224b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3123584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
312456926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
312556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3126584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3127584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3128584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3129584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3130584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3131584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3132584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3133584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3134584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3135584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3136584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3137584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3138584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3139584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3140584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3141584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3142584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
31437784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
31447784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
31457784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
31467784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
31477784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
31487784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
31497784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3150584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3151584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3152584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3153584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3154584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3155584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3156584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3157584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3158a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3159a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3160f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3161f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3166f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3167f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3168f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3169590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3170590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3171f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3172f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3173f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3174f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3175f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3176f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3177f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
31788a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
31798a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3180f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3181f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3182f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3183f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3184f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3185f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3186f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3187f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3188f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3189f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3190f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3191f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3192f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3193f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3194f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3195f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3196f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3197f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3198f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3199f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3200f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3201f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3202f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3203f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3204f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3205f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3206f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3207c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3208c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3209c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3210c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3211c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3212c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3213c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3214c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3215c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3216c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3217c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3218c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3219c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3220c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3221c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3222c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3223c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3224c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3225c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3226c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3227c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3228c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3229c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3230c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3231580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3232580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3233580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3234580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3235580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3236580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3237580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3238580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3239580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3240580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3241580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3242580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3243580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3244580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3245580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3246580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3247580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3248580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3249580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3250580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3251580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3252580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3253580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3254580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3255580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3256580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
32578a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
32588a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3259580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3260580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3261580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3262580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3263580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3264580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3266580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3268580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3269580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3270580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3271580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3272580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3273580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3274580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3275580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3276580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3277580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3278580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3279580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3280580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3281580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3282580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
32830afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
32840afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
32850afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
32860afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
32870afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3288580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3289580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3290580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3291580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3292580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3293580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3294580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3295580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3296580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3297580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3298580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3299580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3300580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3301580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3302580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
33037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
33047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
33057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
33067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
33077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
33087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
33097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3310326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3311326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
33127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3313326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3314326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
33157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
33167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
33177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
33188a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33198a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
33207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
33217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
33227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
33237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
33247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
33257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
33267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
33277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
33287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
33297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
33307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
33317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
33327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
33337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
33347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
33357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
33367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
33377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
33387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
33397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
33407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
33417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
33427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
33437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
33447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
33457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
33467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
33477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
33487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
33497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
33507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
33517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3352293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3353293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3354293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3355293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
33568a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33578a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3358293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3359293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3360293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3361293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3362293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3363293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3364293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3365293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3366293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3367293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3368293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3369293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3370293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3371293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3372293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3373293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3374293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3375293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3376293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3377293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3378293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3379293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3380293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3381293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3382293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3383293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3384293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3385293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3386293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
33898a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33908a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3391293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3392293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3393293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3394293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3395293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3396293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3397293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3398293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3399293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3400293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3401293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3402293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3403293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3404293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3405293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3406293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3407293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3408293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3409293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3410293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3411293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3412293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3413293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3414293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3415293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3416293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3417293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3418293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3419293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
34207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
34217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
34227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3423f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3424f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3425f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
34267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
34277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
34287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
34297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
34307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
34317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
34327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
343316578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
34347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
34357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
34367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
34377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
34387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
34397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
344016578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
34417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
34427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
34437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
34447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
34457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
34467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
34477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
34487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
34497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
34507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
34517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
34527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3453f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3454f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
34550d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
34560d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
34570d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
34580d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
34590d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3460f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3461f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3462f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
34637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
34647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
34657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
34667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3467251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3468251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3469251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3470251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3471251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3472251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3473251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3474251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3475251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3476251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3477251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3478251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3479251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3480251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3481251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3482251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3483251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
34848a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
34858a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3486251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3487251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3488251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3489251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3490251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3491251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3492251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3493251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3494251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3495251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3496251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3497251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3498251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3499251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3500251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3501251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3502251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3503251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3504251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3505251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3506251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3507251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3508251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3509251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3510251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3511251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3512251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3513251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3514251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3515251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3516251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3517251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3518251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3519251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3520251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3521251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3522251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3523251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3524251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3525251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3526251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3527251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3528251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3529251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3530251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3531251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3532251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3533251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3534251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3535251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3536251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3537251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3538a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3539a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3540a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3541a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3542a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3543a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3544a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3545a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3546a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3547a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3548a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3549a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3550a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3551a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3552a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3553a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3554a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3555a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3556a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3557a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3558a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3559a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3560a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3561a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3562a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3563a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3564a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3565a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3566a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3567a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3568a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3569a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3570a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3571a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3572a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3573a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3574eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3575eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3576eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3577eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3578eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3579eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3580eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3581eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3582eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3583eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3584eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3585eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3586eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3587eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3588eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3589eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3590ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3591ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3592ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3593ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3594ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3595ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3596ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3597ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3598ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3599ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3600ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3601ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3602ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3603ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
36041355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3607ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
36081355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3609ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
36157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3616ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
36209ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
36219ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
36229ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
36239ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
36249ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
36259ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36269ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36279ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
36289ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
36299ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
36309ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
36319ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
36329ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
36339ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
36349ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
36359ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
36369ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3637548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3638548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3639548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3640548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3641548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3642548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3643548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3644548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3645548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3646548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3647548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3648548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3649548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3650548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
36511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3652ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3654ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
36551355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3659548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3660548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3661548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
36627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
36637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
36647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
36657b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
36667b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
36677b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
36687b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
36697b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
36707b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36717b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
36727b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
36737b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36747b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
36757b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
36767b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
36777b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
36787b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
36797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
36807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
36817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
36827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
36837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
36847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3686ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
36887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
36897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
36907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
36917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
36927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
36937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3694ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3695ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3696ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3697ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
36987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3699ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3700ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3701ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
37027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
37037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3705aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3706ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3707ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
37087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
37097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
37107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
37117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
37127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
37137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
37157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3716aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
37177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
37187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
37197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
37207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
37217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
37227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
37247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
37257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
37267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
37277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
37287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
37297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
37307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
37317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3732ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3733ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3734ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3735ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
37367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3737ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3738ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3739ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
37407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
37417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3742ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3743ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
37447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3745ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
37467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
37477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
37487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
37497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
37507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3751ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3752ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3753ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3754ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
37552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
37562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
37572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
37582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
37592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
37602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
37622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
37632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
37642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
37652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
37662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
37672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
37682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
37692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
37712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
37722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
377314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
377414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
377514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
377614605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
377714605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
377814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
377914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
378014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
378114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
378214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
378314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
378414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
378514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
378614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
378714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
378814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
378914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
379014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3791623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3792623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3793623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3794623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3795623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3796623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3797623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3798623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3799623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3800623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3801623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3802623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
3803623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
3804623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
380588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
380688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
380788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
380888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
380988ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
381088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
381188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
381288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
381388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
38147a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
38157a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
38167a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
38177a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
381888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
38197a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
382088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
382188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
382288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
382388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
38241b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
38251b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
38261b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
38271b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
38281b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
38291b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
38301b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
38311b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
38321b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
383388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
383488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
383588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
383688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
3837623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
383812431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
383912431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
384012431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
384112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
38426029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
384312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
384412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
384512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
384612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
384712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
384812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
384912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
385012431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
385112431329d617064d6e72dd040a58c1635cc261abJim Grosbach
385212431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
385312431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
385412431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
385512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
38566029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
385712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
385812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
385912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
386012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
386112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
386212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
386312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
386412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
386512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
386612431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
386712431329d617064d6e72dd040a58c1635cc261abJim Grosbach
38684334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
38694334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
38704334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38714334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
38724334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38734334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
38744334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
38754334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
38766029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
38774334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
38784334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38794334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
38804334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
38814334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
38824334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
38834334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
38844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38854334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
38864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38874334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
38884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
38894334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
38904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
38914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
38926029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
38934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
38944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
38964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
38974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
3898e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
38999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
390050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
39017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3902762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
390318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
3904a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
3905762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
3906b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
3907a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
390818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
39091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
39107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
39117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
3912a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
39130571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
39140571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
39150571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
39167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
39170571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
39187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
3919762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
3920b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
3921a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
39227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
392357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
392403f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
3925fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
3926fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
3927fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
3928fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3929fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
3930fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
3931fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
39327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
39337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
393450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
39357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
39367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
393750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
393857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
393957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
394057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
394157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
394257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
394357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
394457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
394557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
394657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
394757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
394857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
394957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
395057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
395157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
395257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
395357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
395457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
395557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
395657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
3957eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach      return Error(E,
3958eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach                   "alignment specifier must be 16, 32, 64, 128, or 256 bits");
3959eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 16:  Align = 2; break;
3960eeaf1c1636c664c707fd9ecc96916fd20ddf137aJim Grosbach    case 32:  Align = 4; break;
396157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
396257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
396357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
396457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
396557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
396657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
396757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
396857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
396957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
397057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
397157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
397257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
397357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
397457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
397557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
397657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
397757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
397857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
397957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
398057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
398157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
398257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
398357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
398457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
398557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
398657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
398757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
398857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
39896cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
39906cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
39916cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
39928a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
39936cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
39948a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
39956cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
39967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
399750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
39980da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
39997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
40007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
40017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
400205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
40037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
40047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
40057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
40067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
40077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
40087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
40097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
40100da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
40110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
40120da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
40130da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
40140da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
40157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
40167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
40177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
40187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
40197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
402005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
40217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
40227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
40237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
402457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
402557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
4026a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
40287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
40297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
40307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
40317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
4032762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
40337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
40347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
40359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
4036d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
40377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
40387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
40397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
40407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
40417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
40427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
40469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
40477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
40487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
40497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
40507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
40517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
40527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
40537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
40540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
40557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
40567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
40570d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
40587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
40599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
406016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
40617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
40627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
40637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
40647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
40657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
40667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
40677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
406857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
40697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
40707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
4071f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
4072f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
4073f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
4074f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
4075f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
4076f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
40779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
40789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
40799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
40809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
40817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
4082a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
4083a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
40847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
40857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
40867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
40877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
408818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4089a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4090a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
409138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4092af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4093af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
40940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4095a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
40960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4097a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
40980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4099a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
41000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
41020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4103a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
41047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4105b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
41087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
41097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
41107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
41117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
41127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
41138a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
41148a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
41157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
41167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
41179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
41187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
41197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
41207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
41217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
41227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
41237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
41247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
41257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
41267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
41277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
41287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
41297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
41307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
41317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
41327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
41337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
41389d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
41399d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
41409d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
41419d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
41429d39036f62674606565217a10db28171b9594bc7Jim Grosbach
41438a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
41448a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
41459d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
41460e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
41470e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
41480e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
41490e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
41500e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
41510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
41520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
41530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
41540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
41550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
41560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
41570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
41580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
41590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
41600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
41610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
41629d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
41639d39036f62674606565217a10db28171b9594bc7Jim Grosbach
41649d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
41659d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
41669d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
41679d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
41689d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
41699d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
41709d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
41719d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
41729d39036f62674606565217a10db28171b9594bc7Jim Grosbach    APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
41739d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
41749d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
41759d39036f62674606565217a10db28171b9594bc7Jim Grosbach    IntVal ^= (uint64_t)isNegative << 63;
41769d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int Val = ARM_AM::getFP64Imm(APInt(64, IntVal));
41779d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
41789d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val == -1) {
41799d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("floating point value out of range");
41809d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
41819d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
41829d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
41839d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
41849d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
41859d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
41869d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
41879d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
41889d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
41899d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("encoded floating point value out of range");
41909d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
41919d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
41929d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
41939d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
41949d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
41959d39036f62674606565217a10db28171b9594bc7Jim Grosbach
41969d39036f62674606565217a10db28171b9594bc7Jim Grosbach  TokError("invalid floating point immediate");
41979d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
41989d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
41999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
42009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
42011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4202fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4203762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4204fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4205fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4206fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4207f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4208f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4209fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4210f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4211f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4212f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4213f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4214f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4215fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4217146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4218146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
421950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
422019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
42215cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
42221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
422350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
42240d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
422519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
42260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
422719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
422819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
42295cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
42305cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
42315cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
42325cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
42335cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
42345cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4235e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4236e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4237e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
423819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4239758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
424067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
42416284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
424267b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4243515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4244515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4245515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4246762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4247515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
424850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
425050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
425150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
425250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4253a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
42541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4255d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
42561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
42578a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
425863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4259079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4260079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
4261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4262b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
426363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
4264515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
4265515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
426650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
426763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4268ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach    if (CE) {
4269ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      int32_t Val = CE->getValue();
4270ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      if (isNegative && Val == 0)
4271ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach        ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
427263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
427450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
427550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
427663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
42779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
42789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
42797597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
42807597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
42817597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
42821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
42839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
42849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42857597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
42867597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
42879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
42889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42897597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
42907597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
42919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
42927597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
42939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
42949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4295a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
42997597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
43001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
43017597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
43029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
43039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
43048a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
43059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
43069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
43079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
43089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
43099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
43109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
43119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
43129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
43139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
43147597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
43159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
43167597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
43179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
43189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
43199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
43209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
43219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
43229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
43239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
43249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
43259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
43269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
43279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
43289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
43299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
43309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4331352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4332352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4333352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4334badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
433589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
43361355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
43375f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
43385f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
433989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
434089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4341352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4342352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4343a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4344352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4345badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4346352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4347352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
43485f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
43495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
43505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
43515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
43525f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
43535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
43545f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
43555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
4356352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4357badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
43583f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
43593f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4360ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
436171725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
436204d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
43632f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
43643f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
43653f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
43663f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
43673f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
43683f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
43693f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
43703f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
43713f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
43723f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
43733f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
43743f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
43753f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
43763f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
43773f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
43783f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
43793f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
43803f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
43813f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
43823f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
43833f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
43843f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
43853f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
43863f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
438752925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4388345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4389352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4390352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4391352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
439200f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
43935f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
43945f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
43955f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
439667ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
439748171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
4398f10154010ec01a6965f86e8c136db79732c92eeeJim Grosbach        Mnemonic == "fsts" ||
4399e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4400352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4401352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4402352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4403352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4404a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4405a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4406a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4407a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4408a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4409a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4410a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4411a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4412a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4413a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4414a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4415a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4416a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4417a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4418a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
441989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
442089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
442189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
442289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
442389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
442489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4425352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4426352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
44273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
44283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
44293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
44303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
44313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4432fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
44331355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4434fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4435eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4436eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
44373443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4438eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4439d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4440eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4441d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
44423443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4443d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4444d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4445eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4446fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4447eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
44483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4449eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4450eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4451eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4452eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4453ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4454ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
44550780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
44562bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
44572bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
44582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
44594af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
44604af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
44611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
44623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4463fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
44643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4465fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4466fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4467fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
446863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4469fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4470fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4471badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4472badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4473d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4474d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
447520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
447620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4477d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4478d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4479d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4480d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4481d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4482d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4483d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4484d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4485d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
44868adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4487d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4488d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4489d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4490d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
44913912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
44923912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
44933912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
44943912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
44953912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
44963912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
44973912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
44983912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
449972f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
450020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
450120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
450220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4503f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4504f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4505f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
450672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
450772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
450872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
450920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
451020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
451120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
451272f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4513f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4514f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
451520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
451620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
451720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4518f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4519f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
452020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
452120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
452220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
452320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
452420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
452520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
452620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
452720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // check against T3.
452820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
452920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
453020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
453120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
453220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
453320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
453420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
453564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
453620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
453720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
453820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
453920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
454020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
454120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
454220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
454320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
454420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
454564944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
454664944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
454764944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
454864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
454964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
455064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
455164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
455264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
455364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
455464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
455564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
455664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
455764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
455864944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
45591de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
456064944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
456164944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
456264944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
456364944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
456464944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
456564944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
456664944f48a1164c02c15ca423a53919682a89074cJim Grosbach
45677f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
45687f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
45697f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
45707f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
45717f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
45727f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
45737f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
45747f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
45757f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
45767f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
45777f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
45787f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
45797f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
45807f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
458164944f48a1164c02c15ca423a53919682a89074cJim Grosbach
458220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4583f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4584f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4585f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4586f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4587f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4588f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4589f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
459072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
459172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
459272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
459372f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
45943912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4595d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4596d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4597d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
45987aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
45997aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
46007aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
46017aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
46027aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
46037aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
46047aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
46057aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
46067aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
46077aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
46087aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
46097aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
46107aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
46117aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
46127aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
46137aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
461421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4615badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4616badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4617badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
461821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
461921d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
462021d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
462121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
462221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
462321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
462421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
462521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4626a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // First check for the ARM-specific .req directive.
4627a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier) &&
4628a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach      Parser.getTok().getIdentifier() == ".req") {
4629a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    parseDirectiveReq(Name, NameLoc);
4630a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // We always return 'error' for this, as we're done with this
4631a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    // statement and don't need to match the 'instruction."
4632a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return true;
4633a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
4634a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
4635badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4636badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4637ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4638badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4639352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4640352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4641a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4642352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
464389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
46441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
464589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4646badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
46470c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
46480c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
46490c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
46500c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
46510c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
46520c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4653ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4654ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
465589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
465689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
465789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
465889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
465989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
466089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4661f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4662f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4663f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4664f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4665f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
466689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
466789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
466889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
466989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
467089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4671f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
467289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
467389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
467489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
467589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
467689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4677f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
467889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
467989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4680ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4681ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
46829717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
46833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
46843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
46853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
46863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
46873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
46883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
46893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
46903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
46911355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
46923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
469333c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
469433c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
469533c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
469633c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4697ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
469833c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
469933c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4700c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4701c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4702c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4703c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4704c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4705c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4706c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
470733c16a27370939de39679245c3dff72383c210bdJim Grosbach
47083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4709f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4710f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
47113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4712f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4713f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
47143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
47153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
47163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4717f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4718f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
47193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4720f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4721badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4723a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4724a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4725a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4726a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4727a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4728a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4729a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4730345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
47315747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
47325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
47335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4734a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4735a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
47367aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
47377aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
47387aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
47397aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
47407aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
47417aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
474281d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
474381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
474481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
474581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
47465747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
47475747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
47485747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
47495747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4750a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
47511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4752cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4753cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4754cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4755a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4756a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4757b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4758a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4759a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
47601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4761cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4762cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4763cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4764a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4765a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
476616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4767cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4768186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4769cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4770186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4771cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4772146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
477334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4774ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4775d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4776d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4777d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
477820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
477920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
478020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
478120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
478220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4783ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4784ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
4785ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
4786ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
4787ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4788cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
4789cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
4790cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
479121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
479221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
4793cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
4794cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
4795cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4796cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
4797cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
4798cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
4799857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
4800857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
4801857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
4802857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
4803857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
4804857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
4805857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4806857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4807857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4808857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
4809857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
4810857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
481168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
481268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
481368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
481468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
481568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
481668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
481768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
481868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
481968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
482068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
482168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4822857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
4823857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
4824857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
4825934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
482655b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
482755b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
4828934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
482955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
483055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
4831934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4832934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4833934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
483455b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
483555b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
4836d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
4837d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
4838d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
483955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
4840d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
4841934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
4842934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4843934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
4844934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
4845934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
4846934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
48479898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
4848ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4849ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4850189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
4851aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
4852aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
4853aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
4854aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
4855aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
4856aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
4857aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
4858aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
4859aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
4860aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
4861aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
4862aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
4863aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
4864aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
4865aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
4866aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
4867aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
4868aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
486976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
487076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
487176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
487276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
487376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
487476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
487576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
487676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
487776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
487876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
487976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
4880f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
4881f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
4882f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
4883f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
48841a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
4885f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
48861a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
4887f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
4888f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
4889f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4890189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
4891189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
4892189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
4893189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
48941a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
4895f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
4896f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
4897b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
4898b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // being allowed in IT blocks, but not being predicable.  It just always
4899b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
4900b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
4901f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
4902f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
4903f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
4904f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
4905a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
4906f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
4907f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
4908f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
4909f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
4910f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
4911f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
4912f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
4913f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
4914f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
4915f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
4916f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
4917f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
4918f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
4919f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
4920f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
4921f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
4922f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
4923c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
4924f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
4925f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
492651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
492751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
4928f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
4929f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4930189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
49312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
49322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
49332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
4934189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
4935189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
4936189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
4937189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4938189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
4939189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
4940189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
4941189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
4942189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
494314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
494414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
494514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
494614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
494714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
494814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
494914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
495014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
495114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
495253642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
495353642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
4954189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
4955189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
4956189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4957189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
4958189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
495914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
4960189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
4961189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
4962189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
4963fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
4964fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
4965fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
4966fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
4967fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
4968fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
4969fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
4970fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
497100c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
4972fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
497393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
497476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
497576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
497676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
497776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
497876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
497993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
498093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
498193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
49827260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
49837260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
49847260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
4985aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
498676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
4987aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
4988aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
498993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
499076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
499193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
499293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
499376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
499476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
4995aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
49967260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
49977260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
49987260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
499993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
500093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
500193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
500276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
500376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
500476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
500576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
500676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
500776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
500876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
50095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
50105402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
50115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
50126dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
5013aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
50145402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
50155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5016aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5017aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
50186dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
50196dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
50206dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
5021aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
50225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
50235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
5024aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
5025aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
50266dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
50276dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
50281e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
50291e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
50308213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
50311e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
50321e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
50331e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
50341e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
5035189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
5036189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5037189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
5038189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
5039189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
504084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVSTLNOpcode(unsigned Opc) {
504184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
504284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  default: assert(0 && "unexpected opcode!");
50439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST1LN
50449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:  case ARM::VST1LNdWB_fixed_Asm_P8:
50459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I8: case ARM::VST1LNdWB_fixed_Asm_S8:
50469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U8:
50479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd8_UPD;
50489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:  case ARM::VST1LNdWB_fixed_Asm_P16:
50499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I16: case ARM::VST1LNdWB_fixed_Asm_S16:
50509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U16:
50519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd16_UPD;
50529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32:  case ARM::VST1LNdWB_fixed_Asm_F:
50539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_F32: case ARM::VST1LNdWB_fixed_Asm_I32:
50549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S32: case ARM::VST1LNdWB_fixed_Asm_U32:
50559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd32_UPD;
50569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:  case ARM::VST1LNdWB_register_Asm_P8:
50579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I8: case ARM::VST1LNdWB_register_Asm_S8:
50589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U8:
50599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd8_UPD;
50609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16:  case ARM::VST1LNdWB_register_Asm_P16:
50619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I16: case ARM::VST1LNdWB_register_Asm_S16:
50629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U16:
50639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd16_UPD;
50649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32:  case ARM::VST1LNdWB_register_Asm_F:
50659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_F32: case ARM::VST1LNdWB_register_Asm_I32:
50669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S32: case ARM::VST1LNdWB_register_Asm_U32:
50679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd32_UPD;
50689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_8:  case ARM::VST1LNdAsm_P8:
50699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_I8: case ARM::VST1LNdAsm_S8:
50709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_U8:
50719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd8;
50729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_16:  case ARM::VST1LNdAsm_P16:
50739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_I16: case ARM::VST1LNdAsm_S16:
50749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_U16:
50759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd16;
50769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_32:  case ARM::VST1LNdAsm_F:
50779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_F32: case ARM::VST1LNdAsm_I32:
50789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_S32: case ARM::VST1LNdAsm_U32:
50799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST1LNd32;
50809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
50819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VST2LN
50829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8:  case ARM::VST2LNdWB_fixed_Asm_P8:
50839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_I8: case ARM::VST2LNdWB_fixed_Asm_S8:
50849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_U8:
50859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd8_UPD;
50869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_16:  case ARM::VST2LNdWB_fixed_Asm_P16:
50879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_I16: case ARM::VST2LNdWB_fixed_Asm_S16:
50889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_U16:
50899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd16_UPD;
50909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32:  case ARM::VST2LNdWB_fixed_Asm_F:
50919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_F32: case ARM::VST2LNdWB_fixed_Asm_I32:
50929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_S32: case ARM::VST2LNdWB_fixed_Asm_U32:
50939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd32_UPD;
50949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8:  case ARM::VST2LNdWB_register_Asm_P8:
50959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_I8: case ARM::VST2LNdWB_register_Asm_S8:
50969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_U8:
50979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd8_UPD;
50989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_16:  case ARM::VST2LNdWB_register_Asm_P16:
50999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_I16: case ARM::VST2LNdWB_register_Asm_S16:
51009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_U16:
51019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd16_UPD;
51029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32:  case ARM::VST2LNdWB_register_Asm_F:
51039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_F32: case ARM::VST2LNdWB_register_Asm_I32:
51049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_S32: case ARM::VST2LNdWB_register_Asm_U32:
51059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd32_UPD;
51069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_8:  case ARM::VST2LNdAsm_P8:
51079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_I8: case ARM::VST2LNdAsm_S8:
51089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_U8:
51099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd8;
51109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_16:  case ARM::VST2LNdAsm_P16:
51119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_I16: case ARM::VST2LNdAsm_S16:
51129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_U16:
51139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd16;
51149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_32:  case ARM::VST2LNdAsm_F:
51159b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_F32: case ARM::VST2LNdAsm_I32:
51169b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_S32: case ARM::VST2LNdAsm_U32:
51179b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VST2LNd32;
511884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
511984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
512084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
512184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVLDLNOpcode(unsigned Opc) {
51227636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
51237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  default: assert(0 && "unexpected opcode!");
51249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD1LN
51259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:  case ARM::VLD1LNdWB_fixed_Asm_P8:
51269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I8: case ARM::VLD1LNdWB_fixed_Asm_S8:
51279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U8:
51289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd8_UPD;
51299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:  case ARM::VLD1LNdWB_fixed_Asm_P16:
51309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I16: case ARM::VLD1LNdWB_fixed_Asm_S16:
51319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U16:
51329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd16_UPD;
51339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32:  case ARM::VLD1LNdWB_fixed_Asm_F:
51349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_F32: case ARM::VLD1LNdWB_fixed_Asm_I32:
51359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S32: case ARM::VLD1LNdWB_fixed_Asm_U32:
51369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd32_UPD;
51379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:  case ARM::VLD1LNdWB_register_Asm_P8:
51389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_I8: case ARM::VLD1LNdWB_register_Asm_S8:
51399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_U8:
51409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd8_UPD;
51419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:  case ARM::VLD1LNdWB_register_Asm_P16:
51429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_I16: case ARM::VLD1LNdWB_register_Asm_S16:
51439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_U16:
51449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd16_UPD;
51459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32:  case ARM::VLD1LNdWB_register_Asm_F:
51469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_F32: case ARM::VLD1LNdWB_register_Asm_I32:
51479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_S32: case ARM::VLD1LNdWB_register_Asm_U32:
51489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd32_UPD;
51499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_8:  case ARM::VLD1LNdAsm_P8:
51509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_I8: case ARM::VLD1LNdAsm_S8:
51519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_U8:
51529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd8;
51539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_16:  case ARM::VLD1LNdAsm_P16:
51549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_I16: case ARM::VLD1LNdAsm_S16:
51559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_U16:
51569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd16;
51579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_32:  case ARM::VLD1LNdAsm_F:
51589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_F32: case ARM::VLD1LNdAsm_I32:
51599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_S32: case ARM::VLD1LNdAsm_U32:
51609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD1LNd32;
51619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
51629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // VLD2LN
51639b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8:  case ARM::VLD2LNdWB_fixed_Asm_P8:
51649b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_I8: case ARM::VLD2LNdWB_fixed_Asm_S8:
51659b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_U8:
51669b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd8_UPD;
51679b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_16:  case ARM::VLD2LNdWB_fixed_Asm_P16:
51689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_I16: case ARM::VLD2LNdWB_fixed_Asm_S16:
51699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_U16:
51709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd16_UPD;
51719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32:  case ARM::VLD2LNdWB_fixed_Asm_F:
51729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_F32: case ARM::VLD2LNdWB_fixed_Asm_I32:
51739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_S32: case ARM::VLD2LNdWB_fixed_Asm_U32:
51749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd32_UPD;
51759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8:  case ARM::VLD2LNdWB_register_Asm_P8:
51769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_I8: case ARM::VLD2LNdWB_register_Asm_S8:
51779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_U8:
51789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd8_UPD;
51799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_16:  case ARM::VLD2LNdWB_register_Asm_P16:
51809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_I16: case ARM::VLD2LNdWB_register_Asm_S16:
51819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_U16:
51829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd16_UPD;
51839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32:  case ARM::VLD2LNdWB_register_Asm_F:
51849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_F32: case ARM::VLD2LNdWB_register_Asm_I32:
51859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_S32: case ARM::VLD2LNdWB_register_Asm_U32:
51869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd32_UPD;
51879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_8:  case ARM::VLD2LNdAsm_P8:
51889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_I8: case ARM::VLD2LNdAsm_S8:
51899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_U8:
51909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd8;
51919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_16:  case ARM::VLD2LNdAsm_P16:
51929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_I16: case ARM::VLD2LNdAsm_S16:
51939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_U16:
51949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd16;
51959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_32:  case ARM::VLD2LNdAsm_F:
51969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_F32: case ARM::VLD2LNdAsm_I32:
51979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_S32: case ARM::VLD2LNdAsm_U32:
51989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return ARM::VLD2LNd32;
51997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
52007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
52017636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
520283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5203f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5204f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5205f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
52069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VST complex aliases.
52079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8: case ARM::VST1LNdWB_register_Asm_P8:
52089b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I8: case ARM::VST1LNdWB_register_Asm_S8:
52099b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U8: case ARM::VST1LNdWB_register_Asm_16:
52109b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_P16: case ARM::VST1LNdWB_register_Asm_I16:
52119b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S16: case ARM::VST1LNdWB_register_Asm_U16:
52129b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32: case ARM::VST1LNdWB_register_Asm_F:
52139b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_F32: case ARM::VST1LNdWB_register_Asm_I32:
52149b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S32: case ARM::VST1LNdWB_register_Asm_U32: {
521584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
521684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
521784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
521884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
521984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
522084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
522184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
522284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
522384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
522484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
522584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
522684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
522784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
522884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
522984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
52309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_8: case ARM::VST2LNdWB_register_Asm_P8:
52329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_I8: case ARM::VST2LNdWB_register_Asm_S8:
52339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_U8: case ARM::VST2LNdWB_register_Asm_16:
52349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_P16: case ARM::VST2LNdWB_register_Asm_I16:
52359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_S16: case ARM::VST2LNdWB_register_Asm_U16:
52369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_32: case ARM::VST2LNdWB_register_Asm_F:
52379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_F32: case ARM::VST2LNdWB_register_Asm_I32:
52389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_register_Asm_S32: case ARM::VST2LNdWB_register_Asm_U32: {
52399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
52409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
52419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
52429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
52439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
52449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
52459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
52469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
52479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
52489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
52499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
52509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
52519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
52529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
52539b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
52549b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
52559b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8: case ARM::VST1LNdWB_fixed_Asm_P8:
52569b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I8: case ARM::VST1LNdWB_fixed_Asm_S8:
52579b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U8: case ARM::VST1LNdWB_fixed_Asm_16:
52589b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_P16: case ARM::VST1LNdWB_fixed_Asm_I16:
52599b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S16: case ARM::VST1LNdWB_fixed_Asm_U16:
52609b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32: case ARM::VST1LNdWB_fixed_Asm_F:
52619b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_F32: case ARM::VST1LNdWB_fixed_Asm_I32:
52629b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S32: case ARM::VST1LNdWB_fixed_Asm_U32: {
526384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
526484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
526584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
526684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
526784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
526884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
526984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
527084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
527184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
527284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
527384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
527484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
527584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
527684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
527784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
52789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
52799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_8: case ARM::VST2LNdWB_fixed_Asm_P8:
52809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_I8: case ARM::VST2LNdWB_fixed_Asm_S8:
52819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_U8: case ARM::VST2LNdWB_fixed_Asm_16:
52829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_P16: case ARM::VST2LNdWB_fixed_Asm_I16:
52839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_S16: case ARM::VST2LNdWB_fixed_Asm_U16:
52849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_32: case ARM::VST2LNdWB_fixed_Asm_F:
52859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_F32: case ARM::VST2LNdWB_fixed_Asm_I32:
52869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdWB_fixed_Asm_S32: case ARM::VST2LNdWB_fixed_Asm_U32: {
52879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
52889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
52899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
52909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
52919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
52929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
52939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
52949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
52959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
52969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
52979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
52989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
52999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
53009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
53019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
53029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
53039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_8: case ARM::VST1LNdAsm_P8: case ARM::VST1LNdAsm_I8:
53049b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_S8: case ARM::VST1LNdAsm_U8: case ARM::VST1LNdAsm_16:
53059b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_P16: case ARM::VST1LNdAsm_I16: case ARM::VST1LNdAsm_S16:
53069b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_U16: case ARM::VST1LNdAsm_32: case ARM::VST1LNdAsm_F:
53079b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST1LNdAsm_F32: case ARM::VST1LNdAsm_I32: case ARM::VST1LNdAsm_S32:
530884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U32: {
530984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
531084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
531184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
531284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
531384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
531484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
531584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
531684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
531784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
531884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
531984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
532084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
532184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
53229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
53239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_8: case ARM::VST2LNdAsm_P8: case ARM::VST2LNdAsm_I8:
53249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_S8: case ARM::VST2LNdAsm_U8: case ARM::VST2LNdAsm_16:
53259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_P16: case ARM::VST2LNdAsm_I16: case ARM::VST2LNdAsm_S16:
53269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_U16: case ARM::VST2LNdAsm_32: case ARM::VST2LNdAsm_F:
53279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_F32: case ARM::VST2LNdAsm_I32: case ARM::VST2LNdAsm_S32:
53289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VST2LNdAsm_U32: {
53299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
53309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
53319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
53329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
53339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
53349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
53359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
53369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
53379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
53389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
53399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
53409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
53419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
53429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
53439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  // Handle NEON VLD complex aliases.
53449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_8: case ARM::VLD1LNdWB_register_Asm_P8:
53459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_I8: case ARM::VLD1LNdWB_register_Asm_S8:
53469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_U8: case ARM::VLD1LNdWB_register_Asm_16:
53479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_P16: case ARM::VLD1LNdWB_register_Asm_I16:
53489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_S16: case ARM::VLD1LNdWB_register_Asm_U16:
53499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_32: case ARM::VLD1LNdWB_register_Asm_F:
53509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_F32: case ARM::VLD1LNdWB_register_Asm_I32:
53519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_register_Asm_S32: case ARM::VLD1LNdWB_register_Asm_U32: {
5352872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5353872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5354872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
535584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
5356872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5357872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5358872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5359872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5360872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5361872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5362872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5363872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5364872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5365872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5366872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5367872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
53689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
53699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_8: case ARM::VLD2LNdWB_register_Asm_P8:
53709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_I8: case ARM::VLD2LNdWB_register_Asm_S8:
53719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_U8: case ARM::VLD2LNdWB_register_Asm_16:
53729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_P16: case ARM::VLD2LNdWB_register_Asm_I16:
53739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_S16: case ARM::VLD2LNdWB_register_Asm_U16:
53749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_32: case ARM::VLD2LNdWB_register_Asm_F:
53759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_F32: case ARM::VLD2LNdWB_register_Asm_I32:
53769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_register_Asm_S32: case ARM::VLD2LNdWB_register_Asm_U32: {
53779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
53789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
53799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
53809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
53819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
53829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
53839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
53849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
53859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
53869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
53879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
53889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
53899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
53909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
53919b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
53929b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
53939b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
53949b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
53959b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
53969b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8: case ARM::VLD1LNdWB_fixed_Asm_P8:
53979b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I8: case ARM::VLD1LNdWB_fixed_Asm_S8:
53989b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U8: case ARM::VLD1LNdWB_fixed_Asm_16:
53999b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_P16: case ARM::VLD1LNdWB_fixed_Asm_I16:
54009b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S16: case ARM::VLD1LNdWB_fixed_Asm_U16:
54019b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32: case ARM::VLD1LNdWB_fixed_Asm_F:
54029b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_F32: case ARM::VLD1LNdWB_fixed_Asm_I32:
54039b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S32: case ARM::VLD1LNdWB_fixed_Asm_U32: {
5404872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5405872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5406872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
540784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
5408872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5409872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5410872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5411872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5412872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
5413872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5414872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5415872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
5416872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
5417872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5418872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5419872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
54209b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54219b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_8: case ARM::VLD2LNdWB_fixed_Asm_P8:
54229b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_I8: case ARM::VLD2LNdWB_fixed_Asm_S8:
54239b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_U8: case ARM::VLD2LNdWB_fixed_Asm_16:
54249b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_P16: case ARM::VLD2LNdWB_fixed_Asm_I16:
54259b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_S16: case ARM::VLD2LNdWB_fixed_Asm_U16:
54269b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_32: case ARM::VLD2LNdWB_fixed_Asm_F:
54279b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_F32: case ARM::VLD2LNdWB_fixed_Asm_I32:
54289b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdWB_fixed_Asm_S32: case ARM::VLD2LNdWB_fixed_Asm_U32: {
54299b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
54309b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
54319b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
54329b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
54339b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
54349b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
54359b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
54369b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
54379b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
54389b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
54399b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
54409b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
54419b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
54429b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
54439b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
54449b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
54459b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
54469b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
54479b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54489b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_8: case ARM::VLD1LNdAsm_P8: case ARM::VLD1LNdAsm_I8:
54499b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_S8: case ARM::VLD1LNdAsm_U8: case ARM::VLD1LNdAsm_16:
54509b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_P16: case ARM::VLD1LNdAsm_I16: case ARM::VLD1LNdAsm_S16:
54519b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_U16: case ARM::VLD1LNdAsm_32: case ARM::VLD1LNdAsm_F:
54529b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD1LNdAsm_F32: case ARM::VLD1LNdAsm_I32: case ARM::VLD1LNdAsm_S32:
5453dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_U32: {
54547636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
54557636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
54567636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
545784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
54587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
54597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
54607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
54617636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
54627636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
54637636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
54647636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
54657636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
54667636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
54677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
54689b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach
54699b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_8: case ARM::VLD2LNdAsm_P8: case ARM::VLD2LNdAsm_I8:
54709b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_S8: case ARM::VLD2LNdAsm_U8: case ARM::VLD2LNdAsm_16:
54719b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_P16: case ARM::VLD2LNdAsm_I16: case ARM::VLD2LNdAsm_S16:
54729b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_U16: case ARM::VLD2LNdAsm_32: case ARM::VLD2LNdAsm_F:
54739b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_F32: case ARM::VLD2LNdAsm_I32: case ARM::VLD2LNdAsm_S32:
54749b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  case ARM::VLD2LNdAsm_U32: {
54759b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    MCInst TmpInst;
54769b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
54779b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    // right place.
54789b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
54799b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
54809b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
54819b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
54829b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
54839b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
54849b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(Inst.getOperand(0).getReg()+1));
54859b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
54869b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
54879b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
54889b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    Inst = TmpInst;
54899b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach    return true;
54909b1b3902882675e5ce35eacd639456bd648324b7Jim Grosbach  }
5491863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the Thumb2 mode MOV complex aliases.
5492863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVsi:
5493863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  case ARM::t2MOVSsi: {
5494863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // Which instruction to expand to depends on the CCOut operand and
5495863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // whether we're in an IT block if the register operands are low
5496863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    // registers.
5497863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    bool isNarrow = false;
5498863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
5499863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
5500863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach        inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
5501863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      isNarrow = true;
5502863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    MCInst TmpInst;
5503863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned newOpc;
5504863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
5505863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
5506863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
5507863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
5508863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
5509863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
5510863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    }
5511863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
5512863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (Ammount == 32) Ammount = 0;
5513863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.setOpcode(newOpc);
5514863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
5515863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (isNarrow)
5516863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
5517863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
5518863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
5519863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Ammount));
5520863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
5521863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
5522863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    if (!isNarrow)
5523863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(
5524863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach          Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
5525863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    Inst = TmpInst;
5526863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach    return true;
5527863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  }
5528863d2af9477e331955a9bee8be1969ce658b59b5Jim Grosbach  // Handle the ARM mode MOV complex aliases.
552923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
553023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
553123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
553223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
553323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
553423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
553523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
553623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
553723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
553823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
553923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
554023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
554123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
554223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
554323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
554423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
554523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
554623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
554723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
554823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
554923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
555023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
555123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
555223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
555323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
555423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
5555ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
5556ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
5557ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
5558ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
5559ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
5560ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
5561ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
5562ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
5563ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
5564ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
5565ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
5566ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
5567ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
556848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
5569ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
5570ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
557171810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
5572ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
557371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
557471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
5575ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
5576ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
557771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
557871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
557971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
558071810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
558183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
558271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
558348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
558448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
558548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
558648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
558748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
558848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
558948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
559048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
559148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
559248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
559348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
559448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
559548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
55960352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
55970352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
55980352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
55990352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
56000352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
56010352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
56020352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
56030352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
56040352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
56050352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
56060352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
56070352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
56080352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
56090352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
56100352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
56110352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
56120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
56130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
56140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
56150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
56160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
56170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
56180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
56190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
56200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
56210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
56220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
56230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
56240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
56250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
56260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
56270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
5628f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
5629f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
5630f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
5631f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
5632f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
5633f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
5634f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
5635f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
5636f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
5637f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
5638f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
5639f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
5640f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
5641f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5642f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
564383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
5644f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
5645f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
5646f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
5647f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
5648f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
5649f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
5650f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
5651f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
5652f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
5653f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
5654f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
5655f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
5656f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
5657f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
5658f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5659f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
5660f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
5661f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
5662da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
5663da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
5664da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
5665da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
5666da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
5667da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
5668da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
5669da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
5670da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
5671da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
5672da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
5673da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
5674da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
5675da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
5676da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
5677da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
5678da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
5679da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
568089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
56810f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
56820f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
56830f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
56840f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
568583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
568689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
568783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
568883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
568989e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
5690f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
5691f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
5692f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
5693f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
5694f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
569583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
5696f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
569783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
569883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
5699f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
5700927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
5701927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
5702927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
5703927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
5704927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
5705927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
5706927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
5707713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
5708713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
5709927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
5710927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
5711927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
5712927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
5713927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
5714927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
5715927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
5716927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
5717927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
5718927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
5719927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
572051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
572151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
572283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
572351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
572483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
572583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
572651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
572751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
572851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
572983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
573051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
573183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
573283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
573351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
5734c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
5735a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
573683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
5737c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
573883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
573983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
5740c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
5741395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
5742395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
574383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
5744395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
574583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
574683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
57473ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
574876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
574976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
575076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
575176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
575276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
575376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
575476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
575576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
575676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
575776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
575876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
575976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
576076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
576176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
576276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
576376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
576476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
576576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
576676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
576776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
576876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
576983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
577076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
577176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
577276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
57738213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
57748213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
57758213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
57768213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
57778213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
57788213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
57798213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
57808213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
57818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
57828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
578383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
57848213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
57858213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
57868213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
57875402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
57885402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
57895402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
57905402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
57915402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
57925402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
579383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
57945402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
57955402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
57965402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
57975402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
57985402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
579983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
58005402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
58015402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
58025402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
58035402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
580483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
58055402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
58065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
58075402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
58085402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
58095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
581083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
58115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
58121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
58131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
58141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
58151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
58161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
5817c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
5818c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
5819c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
58201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
58211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
58221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
58231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
58241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
58251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
58261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
58271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
58281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
58291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
58301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
583183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
58321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
58331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
58341ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
58351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
58361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
58371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
58381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
58391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
58401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
58411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
58421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
58431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
58441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
58451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
58461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
58471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
58481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
58491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
58501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
58511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
585283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
58531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
58541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
58551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
5856326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
585750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
585850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
585950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
5860326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
5861326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
5862326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
5863326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
5864326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
5865326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
5866326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
586750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
586850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
586950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
587050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
587150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
587250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
587350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
587450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
5875326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
5876326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
5877326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
5878326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
5879326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
5880326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5881326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
5882326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
588383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
5884326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
5885326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
5886326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
588789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
588889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
588989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
589089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
589189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
589289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
589389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
589489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
589589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
5896f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
5897f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
589889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
589989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
590089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
590189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
590289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
590389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
590489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
5905f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5906f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
5907f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
5908f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
5909f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
5910f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
5911f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
5912f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
591389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
591489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
5915f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
591683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
5917f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
5918f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
591947a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
592047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
592147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
5922194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
59231a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
592447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
592547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
592647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
592747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
592847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
592947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
593047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
593147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
593247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
593347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
593447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
593547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
593647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
593747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
593847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
593947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
5940f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
5941f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
594247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
5943f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
5944f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
5945f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
594647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
5947194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
5948194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
5949194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
5950194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
5951194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
5952194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
5953194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
59544ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
5955194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
5956194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
5957194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
595847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
595947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
596047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
5961fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
5962fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
5963fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
5964fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
5965fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
5966fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
596719cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
5968193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
5969193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
597019cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
5971e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
5972189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
5973189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
5974a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
5975a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
5976a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
5977a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
5978189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
5979a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
5980189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5981f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
598283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
598383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
598483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
598583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
598683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
5987f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
5988a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
5989a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
5990a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
5991a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
5992a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
5993fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
5994fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
5995e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
5996e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5997e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
5998e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
5999e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
6000e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
6001e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
6002e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
600316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6004e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
6005e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
6006e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
600716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6008e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
6009e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
6010e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
601147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
6012b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
601388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
601488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
6015f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
6016f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
601747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
601847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
6019194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
6020194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
6021194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
6022194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
6023fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
602416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6025c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
6026146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
6027fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
6028fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
60291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
6030ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
6031ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
6032ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
60331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
6034515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
60351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
60369a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
60379a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
6038515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
60391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
6040515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
60411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
6042515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
60431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
6044a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  else if (IDVal == ".unreq")
6045a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return parseDirectiveUnreq(DirectiveID.getLoc());
6046ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
6047ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
6048ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
60491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
6050ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
60511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
6052ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
6053ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
6054ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
6055ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
6056ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
6057ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
6058aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
6059ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
6060ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
6061ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
606216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6063ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
6064ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
6065ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
6066b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
6067ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
6068ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
6069ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
6070b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6071ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
6072ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
6073ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
60741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
6075515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
60761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
6077515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
6078515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
6079b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6080515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
60819a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
60829a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
60839a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
60849a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
60859a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
60869a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
60879a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
60889a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
60899a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
60909a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
60919a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
60929a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
60939a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
60949a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
60959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
60969a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
6097515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6098515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6099515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
61001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
6101515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
61021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
61036469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
61046469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
61056469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
61066469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
61076469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
61086469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
61096469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
61106469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
61116469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
61126469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
6113d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Tok.getIdentifier();
61146469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
61156469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
61166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
6117d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement))
6118515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
6119b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6120515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
61216469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
61226469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
6123d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
61246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
61256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
6126642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
6127642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
6128642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
6129515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6130515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6131515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
61321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
6133515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
61341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
613518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
6136515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
6137515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
613838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
613958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
6140b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
614158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
61429e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
6143515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
6144515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
6145515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6146515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
614718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
6148b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6149515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6150515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
6151515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
6152515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6154515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
61551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
6156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
61571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
615818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
6159515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
6160515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
616118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
616258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
6163b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
616458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
6165b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
6166515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
6167515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
6168515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6169515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
617018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
6171b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
6172515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
617332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
617498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
6175ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
617698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
617732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
617898447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
6179ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
618098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
6181eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
61822a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
6183515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
6184515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
6185515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
6186a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveReq
6187a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= name .req registername
6188a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
6189a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the '.req' token.
6190a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  unsigned Reg;
6191a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  SMLoc SRegLoc, ERegLoc;
6192a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (ParseRegister(Reg, SRegLoc, ERegLoc)) {
6193a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
6194a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "register name expected");
6195a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
6196a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6197a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  // Shouldn't be anything else.
6198a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6199a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
6200a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(Parser.getTok().getLoc(),
6201a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                 "unexpected input in .req directive.");
6202a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
6203a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6204a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Consume the EndOfStatement
6205a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6206a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (RegisterReqs.GetOrCreateValue(Name, Reg).getValue() != Reg)
6207a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(SRegLoc, "redefinition of '" + Name +
6208a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach                          "' does not match original.");
6209a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6210a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
6211a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
6212a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
6213a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach/// parseDirectiveUneq
6214a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach///  ::= .unreq registername
6215a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbachbool ARMAsmParser::parseDirectiveUnreq(SMLoc L) {
6216a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Identifier)) {
6217a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    Parser.EatToEndOfStatement();
6218a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach    return Error(L, "unexpected input in .unreq directive.");
6219a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  }
6220a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  RegisterReqs.erase(Parser.getTok().getIdentifier());
6221a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  Parser.Lex(); // Eat the identifier.
6222a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach  return false;
6223a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach}
6224a39cda7aff2d379ad9c15500319ab037baa48747Jim Grosbach
622590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
622690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
62279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
6228ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
622994b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
623094b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
623190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
6232ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
62333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
62340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
62350692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
62363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
6237