ARMAsmParser.cpp revision d7ea73a4909fc3200a1cecd2b420d7ace2180b70
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
48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
67f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
75a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
77f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
83ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
860d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  bool parseDirectiveARM(SMLoc L);
961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
99515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
10289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
104fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
10516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
106ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
108ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
109ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
110ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
111ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
112ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
11347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
11447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
11547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
117194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
119acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
120acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
121acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
12232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
123ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
124ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
12532869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
126acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
127acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
128acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
129ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1330692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
13889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
142f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1488bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1508bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
157f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
159c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
162293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
164251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1659d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
166862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
1677636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind, unsigned &Index);
168ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
169ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
170a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
171a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
172a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
173a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
174eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
175eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
176ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
177ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1809ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1819ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
182548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
183548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
185ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
1972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
19814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
19914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
200623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
201623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
20288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
20388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
20412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
20512431329d617064d6e72dd040a58c1635cc261abJim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
20612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  bool cvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
20712431329d617064d6e72dd040a58c1635cc261abJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
2084334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
2094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                     const SmallVectorImpl<MCParsedAsmOperand*> &);
2104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  bool cvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
2114334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
212189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
213189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
214189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
21583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  bool processInstruction(MCInst &Inst,
216f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
217d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
218d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
219189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
220ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
22147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
222194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
224194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
225194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
22647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
22747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
228ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
22994b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
230ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
23132869205052430f45d598fba25ab878d8b29da2dEvan Cheng
232ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
233ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
237ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
238ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2391355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
242189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
24547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
24647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
250ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
25116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
25216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2533a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2543a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
257146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2649b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_FPImmediate,
26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
272460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
27321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
27421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
27521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
27621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
277862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
27898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    k_VectorListAllLanes,
2797636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    k_VectorListIndexed,
28021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
28121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
28221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
28321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
28421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
28521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
287a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
28924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
290a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
297fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
298fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
299fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
300fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
3019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
3029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
3039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
3049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
30589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
30689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
30789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
30889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
30989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
31089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
31189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
31289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
313a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
314a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
326a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
327a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
329862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
330862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
331862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
332862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
3337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned LaneIndex;
334862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
335862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3368155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
337460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
338460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
339460a90540b045c102012da2492999557e6840526Jim Grosbach
340460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
341cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
342cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
34316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3449d39036f62674606565217a10db28171b9594bc7Jim Grosbach    struct {
3459d39036f62674606565217a10db28171b9594bc7Jim Grosbach      unsigned Val;       // encoded 8-bit representation
3469d39036f62674606565217a10db28171b9594bc7Jim Grosbach    } FPImm;
3479d39036f62674606565217a10db28171b9594bc7Jim Grosbach
3486a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
350a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
35657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
35757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
35857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                // n = alignment in bytes (8, 16, or 32)
3597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
360e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
364f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
365f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
366f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
370580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
371e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
372580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
373e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
374e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
375e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
376e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
377e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
378af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
37992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
38092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
38192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
38292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
383af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
389293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
391a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
39216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
393146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
394146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
395762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
396762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
397762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
399762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
4018462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
4028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
40489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
40589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
4078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
408762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
41021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
412762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
41624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
418862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
41998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    case k_VectorListAllLanes:
4207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    case k_VectorListIndexed:
421862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
422862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
425fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
426fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4279b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4289b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4299b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
43021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
431762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
43321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_FPImmediate:
4349d39036f62674606565217a10db28171b9594bc7Jim Grosbach      FPImm = o.FPImm;
4359d39036f62674606565217a10db28171b9594bc7Jim Grosbach      break;
43621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
437706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
438706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
440e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
44221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
44521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
44821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
449a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
452580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
456e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
45721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
458af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
45992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
46321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
464293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
465293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
466460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
467460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
468460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
469762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
470762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
47116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
473762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
474762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
47821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
482fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
484fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
485fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
486fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
489a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
490a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4947729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
496a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
50024d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
5018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
5028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
503cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
50421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Immediate && "Invalid access!");
505cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
506cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
507cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
5089d39036f62674606565217a10db28171b9594bc7Jim Grosbach  unsigned getFPImm() const {
50921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_FPImmediate && "Invalid access!");
5109d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return FPImm.Val;
5119d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
5129d39036f62674606565217a10db28171b9594bc7Jim Grosbach
513460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
514460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
515460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
516460a90540b045c102012da2492999557e6840526Jim Grosbach  }
517460a90540b045c102012da2492999557e6840526Jim Grosbach
518706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
521706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
522706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
528584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
52921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
531584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
532584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
53321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
53421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
53621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
53721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
53821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
53921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
54021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
54121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isFPImm() const { return Kind == k_FPImmediate; }
542a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
544a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
545a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
546a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
547a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
548a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
549a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
55072f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
55272f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
55372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
55472f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
55572f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
55672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
55772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
55872f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
56072f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
56172f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
56272f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
56372f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
56472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
56572f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
5696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
574587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_1() const {
575587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (Kind != k_Immediate)
576587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach      return false;
577587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
578587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
579587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
580587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 2;
581587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
582587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  bool isImm0_3() const {
583587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (Kind != k_Immediate)
584587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach      return false;
585587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
586587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    if (!CE) return false;
587587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    int64_t Value = CE->getValue();
588587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach    return Value >= 0 && Value < 4;
589587f5062b9e4532c4f464942e593cb87c58ac153Jim Grosbach  }
59083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
59121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
59283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
59383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
59483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
59583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
59683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
59783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
59883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
59921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
60083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
60183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
60383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
6067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
60721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
6087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
6097c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
6117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
6127c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
6137c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
614730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  bool isImm0_63() const {
615730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (Kind != k_Immediate)
616730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach      return false;
617730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
618730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    if (!CE) return false;
619730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    int64_t Value = CE->getValue();
620730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach    return Value >= 0 && Value < 64;
621730fe6c1b686fe71c8e549b0f955e65a6a49d3ffJim Grosbach  }
6223b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm8() const {
6233b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6243b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6253b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6263b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6273b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6283b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 8;
6293b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6303b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm16() const {
6313b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6323b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6333b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6343b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6353b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6363b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 16;
6373b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6383b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm32() const {
6393b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6403b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6413b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6423b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6433b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6443b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value == 32;
6453b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6466b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm8() const {
6476b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6486b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6496b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6506b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6516b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6526b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 8;
6536b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6546b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm16() const {
6556b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6566b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6576b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6586b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6596b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6606b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 16;
6616b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6626b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm32() const {
6636b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6646b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6656b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6666b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6676b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6686b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 32;
6696b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6706b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  bool isShrImm64() const {
6716b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (Kind != k_Immediate)
6726b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach      return false;
6736b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6746b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    if (!CE) return false;
6756b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    int64_t Value = CE->getValue();
6766b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach    return Value > 0 && Value <= 64;
6776b044c26094a9f86da7d12945b00a47a5f07cf6dJim Grosbach  }
6783b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_7() const {
6793b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6803b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6813b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6823b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6833b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6843b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 8;
6853b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6863b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_15() const {
6873b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6883b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6893b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6903b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6913b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
6923b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 16;
6933b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
6943b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  bool isImm1_31() const {
6953b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (Kind != k_Immediate)
6963b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach      return false;
6973b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6983b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    if (!CE) return false;
6993b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    int64_t Value = CE->getValue();
7003b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach    return Value > 0 && Value < 32;
7013b8991cc98a469cbf8d9fa2a2ad971f46b8b6fd2Jim Grosbach  }
702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
70321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
708f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
709f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
71121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
7154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
7164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
7174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
718ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  bool isImm0_32() const {
719ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Kind != k_Immediate)
720ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      return false;
721ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
722ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (!CE) return false;
723ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    int64_t Value = CE->getValue();
724ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    return Value >= 0 && Value < 33;
725ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  }
726fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
72721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
728fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
729fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
730fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
731fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
732fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
733fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
734ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
73521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
736ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
737ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
738ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
739ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
740ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
741ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
742ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
743ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
744ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
74521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
746ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
747ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
748ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
749ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
750ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
751ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
75270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
75321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
75470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
75570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
75670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
75770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
75870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
75970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
760f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
76121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
762f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
763f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
764f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
765f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
766f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
767f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
768f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
76921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
770f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
771f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
772f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
773f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
774f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
775f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
7766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
77721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
7786bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
7796bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7806bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
7816bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
7826bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
7836bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
784e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  bool isARMSOImmNot() const {
785e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (Kind != k_Immediate)
786e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach      return false;
787e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
788e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    if (!CE) return false;
789e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    int64_t Value = CE->getValue();
790e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    return ARM_AM::getSOImmVal(~Value) != -1;
791e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
7923bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isARMSOImmNeg() const {
7933bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (Kind != k_Immediate)
7943bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach      return false;
7953bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7963bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
7973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
7983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getSOImmVal(-Value) != -1;
7993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
8006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
80121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
8026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
8036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
8056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
8066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
8076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
80889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  bool isT2SOImmNot() const {
80989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (Kind != k_Immediate)
81089a633708542de5847e807f98f86edfefc9fc019Jim Grosbach      return false;
81189a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
81289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    if (!CE) return false;
81389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    int64_t Value = CE->getValue();
81489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    return ARM_AM::getT2SOImmVal(~Value) != -1;
81589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
8163bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  bool isT2SOImmNeg() const {
8173bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (Kind != k_Immediate)
8183bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach      return false;
8193bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8203bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    if (!CE) return false;
8213bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    int64_t Value = CE->getValue();
8223bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    return ARM_AM::getT2SOImmVal(-Value) != -1;
8233bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
824c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
82521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
826c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
827c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
828c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
829c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
830c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
831c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
83221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
83321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
83421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
83521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
83621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
83721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
83821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
83921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
84021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
84121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
84221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
84321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
84421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
845f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
846430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy ==ARM_AM::no_shift;
847f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
84857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
849f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
850ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
8517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
85257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
85357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
85457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
85557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
85657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
857ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
85957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
861e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
863e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
864e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
867039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
86821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
869039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
870039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
871039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
872039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
873039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
874039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
875039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
8762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
87757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
8782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
879e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
8802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
881e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
8822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
883e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
884e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
8862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
88821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
8892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
89021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
8912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
8922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
8932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
8952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
896251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
897251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
8982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
8997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
900681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
901681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
902681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
903681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
904681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return true;
90557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
9067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
907e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
909e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
910e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
9110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
912681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Val == INT32_MIN;
9137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
9147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
915e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
91657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
9177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
921e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
92257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
92357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
9247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
9257f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
9267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
9277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
92857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
929ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
930ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
931ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
932ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
93357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
93457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
935ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
936ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
937e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
938ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
939e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
940ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
941ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
942ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
9437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
9447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
9457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
946e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
94757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
94887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
949e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
950e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
95160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
95260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
953e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
95457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
95560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
95660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
957e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
958e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
959ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
960ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
96138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
962e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
96357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
96438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
96538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
966e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
967e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
96838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
96938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
97048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
971e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
97257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
97348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
97448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
975e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
976e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
97748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
97848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
979ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
98057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
98157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
982ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
983ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
984e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
986ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
987505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
988a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
98957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
991a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
992e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
993e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
995a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
996b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
99757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
998b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
999b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
1000e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1001e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1002b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
1003b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
10047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
100557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1006f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
10077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
1008e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1009e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10104d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
1011f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1012f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
101357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1014f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
1015f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
1016e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1017e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1018f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
1019f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1020a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
102157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1022a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1023a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
1024df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    if (!Memory.OffsetImm) return false;
1025e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1026df33e0d05e6b7dc3d65cdb96e52fb6fb6b07f876Jim Grosbach    return (Val == INT32_MIN) || (Val > -256 && Val < 0);
1027a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1028a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
102957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1030a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
1031a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
1032e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1033e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
1034a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
1035a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
10367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
103709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
103809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
103909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
104021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
104109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
104209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
104357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
1044ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
10457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
1046e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
1047e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
10480da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
10497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
105121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
10527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
10537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1054ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
10557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
105663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
1057ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
10582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
10592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Kind != k_Immediate)
10602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      return false;
10612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
10632bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
10642bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
10652bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
10662bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
106821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
106921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
10703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
1072862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
1073862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Kind != k_VectorList) return false;
1074862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
1075862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1076862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1077280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  bool isVecListTwoD() const {
1078280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    if (Kind != k_VectorList) return false;
1079280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    return VectorList.Count == 2;
1080280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
1081280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
1082cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
1083cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    if (Kind != k_VectorList) return false;
1084cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
1085cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1086cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1087b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
1088b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    if (Kind != k_VectorList) return false;
1089b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
1090b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1091b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
10924661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  bool isVecListTwoQ() const {
10934661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach    if (Kind != k_VectorList) return false;
10944661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach    //FIXME: We haven't taught the parser to handle by-two register lists
10954661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach    // yet, so don't pretend to know one.
10964661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach    return VectorList.Count == 2 && false;
10974661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach  }
10984661d4cac3ba7f480a91d0ccd35fb2d22d9692d3Jim Grosbach
109998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  bool isVecListOneDAllLanes() const {
110098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Kind != k_VectorListAllLanes) return false;
110198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return VectorList.Count == 1;
110298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
110398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
110413af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  bool isVecListTwoDAllLanes() const {
110513af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    if (Kind != k_VectorListAllLanes) return false;
110613af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach    return VectorList.Count == 2;
110713af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach  }
110813af222bab6fdc77d8193eb38e78a9cbed1d9d1fJim Grosbach
11097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  bool isVecListOneDByteIndexed() const {
11107636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (Kind != k_VectorListIndexed) return false;
11117636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return VectorList.Count == 1 && VectorList.LaneIndex <= 7;
11127636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
11137636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1114460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
1115460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1116460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
1117460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1118460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
1119460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1120460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
1121460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1122460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
1123460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
1124460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
1125460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1126460a90540b045c102012da2492999557e6840526Jim Grosbach
11270e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
11280e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (Kind != k_Immediate)
11290e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach      return false;
11300e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11310e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
11320e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
11330e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
11340e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
11350e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
11360e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
11370e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
1138460a90540b045c102012da2492999557e6840526Jim Grosbach
1139ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
1140ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Kind != k_Immediate)
1141ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      return false;
1142ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1143ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
1144ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
1145ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
1146ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
1147ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
1148ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1149ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
11506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
11516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Kind != k_Immediate)
11526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      return false;
11536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
11556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
11566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
11576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
11586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
11596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
11606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
11616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
11626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
11636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
11646248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
11656248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Kind != k_Immediate)
11666248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      return false;
11676248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11686248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
11696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
11706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
11716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
11726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
11736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
11746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
11756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
11766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
11776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
11786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
11796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
11806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1181f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
1182f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (Kind != k_Immediate)
1183f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      return false;
1184f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1185f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1186f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1187f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1188f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1189f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1190f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1191f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1192f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1193f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
11943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
119514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
119614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
119714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
119814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
11993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
12003483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
12013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
12023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
12033483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
12048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1205345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
12068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
120704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
120804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
12098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
12108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1211fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1212fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1213fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1214fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1215fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
12169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
12179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
12189b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
12199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
12209b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
12219b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
12229b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
12239b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
12249b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
12259b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
122689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
122789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
122889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
122989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
123089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
123189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
123289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
123389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
123489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
123589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1236d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1237d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1238d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1239d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1240d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1246af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1248430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedReg() &&
1249430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedRegOperands() on non RegShiftedReg!");
1250af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1251af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1253af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1255e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1256af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1257152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1258430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    assert(isRegShiftedImm() &&
1259430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach           "addRegShiftedImmOperands() on non RegShiftedImm!");
1260af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
126192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1262af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
126392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
126492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
12660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1268580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
12690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
12700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
127187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
12727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
12735fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
12745fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
12757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
12767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
127787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
127887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
12790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
12800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
12810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
12820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
12830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
12840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
12850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
12860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
12877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
12887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
12897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
12907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
12917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
12927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1297293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1298293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1299293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1300293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
13043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
13056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
13076b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
13086b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
13099d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
13109d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13119d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getFPImm()));
13129d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
13139d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1314a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1315a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1316a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1317a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1318a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1319a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1320a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1321a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
132272f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
132372f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
132472f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
132572f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
132672f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
132772f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
132872f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
132972f39f8436848885176943b0ba985a7171145423Jim Grosbach
133072f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
133172f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
133272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
133372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
133472f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
133572f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
133672f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
133772f39f8436848885176943b0ba985a7171145423Jim Grosbach
1338f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1339f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1340f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1341f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1342f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1343f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1344f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1345f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
13464a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
13474a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13484a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
13494a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
13504a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13514a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
13524a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
13534a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
135470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
135570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
135670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
135770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
135870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
135970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
136070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1361ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1362ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
137289a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  void addT2SOImmNotOperands(MCInst &Inst, unsigned N) const {
137389a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
137489a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // The operand is actually a t2_so_imm, but we have its bitwise
137589a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    // negation in the assembly source, so twiddle it here.
137689a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
137789a633708542de5847e807f98f86edfefc9fc019Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
137889a633708542de5847e807f98f86edfefc9fc019Jim Grosbach  }
137989a633708542de5847e807f98f86edfefc9fc019Jim Grosbach
13803bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addT2SOImmNegOperands(MCInst &Inst, unsigned N) const {
13813bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13823bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a t2_so_imm, but we have its
13833bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
13843bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13853bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
13863bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
13873bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1388e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  void addARMSOImmNotOperands(MCInst &Inst, unsigned N) const {
1389e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1390e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // The operand is actually a so_imm, but we have its bitwise
1391e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    // negation in the assembly source, so twiddle it here.
1392e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1393e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(~CE->getValue()));
1394e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach  }
1395e70ec8463720b5990f0d1ab8d9b6ab56ca1d01c3Jim Grosbach
13963bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  void addARMSOImmNegOperands(MCInst &Inst, unsigned N) const {
13973bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
13983bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // The operand is actually a so_imm, but we have its
13993bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    // negation in the assembly source, so twiddle it here.
14003bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14013bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(-CE->getValue()));
14023bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach  }
14033bc8a3d3afe3ddda884a681002e24850099b719eJim Grosbach
1404706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1405706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1406706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1407706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1408706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
14097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
14107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1411e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1412505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1413505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
141457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
141557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
141657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
141757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
141857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
141957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
14207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
14217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1422e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1423e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
14247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
14257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
14267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
14277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
14287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
14297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
14307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
14317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1432e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1433e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1435e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1436e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
14377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1438ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1439ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1440039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1441039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1442039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1443039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1444039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1445039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1446039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1447039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1448039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1449039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1450039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1451039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1452039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1453039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
14542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
14552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1456e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1457e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
14582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
14592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
14602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
14612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
14622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
14632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
14642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
14652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1466e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
14672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1468e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1469e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
14702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
14722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
14732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
14742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
147521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
14762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
14772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
14782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
14792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1480251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
14812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
14822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
14832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
14842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
14852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
14862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
14872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
14882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
14892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1490251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
14912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
14922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
14942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
14957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
14967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1497681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // If we have an immediate that's not a constant, treat it as a label
1498681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // reference needing a fixup. If it is a constant, it's something else
1499681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    // and we reject it.
1500681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    if (isImm()) {
1501681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateExpr(getImm()));
1502681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1503681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach      return;
1504681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach    }
1505681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach
15067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1507e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
15087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
15097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
15107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
15117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
15127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1513e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
15147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
15167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1517a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1518a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1519e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1520e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1521a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1522a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1523a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1524b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1525b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1526b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1527e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1528e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1529b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1530b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1531b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
15327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
15337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1534e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1535e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
15367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1537ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1538ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1539f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1540f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1541f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1542f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1543a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1544f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1545a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1546a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1547a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1548a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1549a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
155021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
1551a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1552a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1553a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1554a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1555a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1556a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1557e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1558e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1559a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1560a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1561a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
15627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
15637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
156409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
156521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
156609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
156709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
156809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
156909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
157009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
157109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1572e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1573e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
15747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
157692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
15777f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
15787f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1579e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1580e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
15817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
15827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
15837f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
15847f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1585e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1586e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
15877f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
15887f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
15897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
15907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1591430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach    unsigned Val =
1592430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach      ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1593430052b084de7ab4eb6162b9f1a6a16bfb2a80adJim Grosbach                        Memory.ShiftImm, Memory.ShiftType);
1594e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1595e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
15967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
15977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1598d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1599ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1600ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1601e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1602e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1603e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1604ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1605ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
16067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
16077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1608e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1609e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
161014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
16113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
161260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
161360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1614e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1615e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
161660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
161748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
161848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
161938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
162038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1621e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1622e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
162338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
162438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
162538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
162648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
162748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1628e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1629e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
163048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
163160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
163260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1633ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1634ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1635e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1636e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1637ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1638ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1639ecd858968384be029574d845eb098d357049e02eJim Grosbach
16407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
16417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
16427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
16447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
16457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
164663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
16477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
16487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1649f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1650ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
16512bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
16522bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
16532bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
16542bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
16552bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
16562bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
16572bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
16582bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
16592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
16602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
16612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
16622bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
16637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
16647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
16657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1666f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1667f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1668f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1669f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1670f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1671f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1672f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1673f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1674f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1675f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1676f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1677f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1678ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1679ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1680584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1681584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1682584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1683584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1684584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1685a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1686a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1687a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1688a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1689a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
16906029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  void addVecListOperands(MCInst &Inst, unsigned N) const {
1691862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1692862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1693862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1694862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
16957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  void addVecListIndexedOperands(MCInst &Inst, unsigned N) const {
16967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
16977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
16987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(VectorList.LaneIndex));
16997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
17007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1701460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1702460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1703460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1704460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1705460a90540b045c102012da2492999557e6840526Jim Grosbach
1706460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1707460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1708460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1709460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1710460a90540b045c102012da2492999557e6840526Jim Grosbach
1711460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1712460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1713460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1714460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1715460a90540b045c102012da2492999557e6840526Jim Grosbach
17160e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
17170e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17180e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
17190e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
17200e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17210e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
17220e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
17230e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1724ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1725ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1726ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1727ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1728ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1729ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1730ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1731ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1732ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1733ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1734ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1735ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
17366248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
17376248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17386248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
17396248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17406248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
17416248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
17426248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
17436248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
17446248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
17456248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
17466248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
17476248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
17486248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
17496248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
17506248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
17516248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
17526248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
17536248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
17546248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
17556248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
17566248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
17576248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
17586248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
17596248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
17606248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
17616248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
17626248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
17636248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1764f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1765f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1766f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1767f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1768f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1769f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1770f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1771f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1772f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1773f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1774f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1775f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1776b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1777b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
177889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
177921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
178089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
178189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
178289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
178389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
178489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
178589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
17863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
178721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1788345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1789345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1790345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
17913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1792345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1793345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1794fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
179521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1796fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1797fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1798fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1799fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1800fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1801fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1802fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
180321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
1804fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1805fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1806fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1807fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1808fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1809fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
18109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
18119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
18129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
18139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
18149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
18159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
18169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
18179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
1818d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
181921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
1820d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1821d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1822d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1823d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1824d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1825d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
18263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
182721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
1828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
18323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1833a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1834a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
183550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
183621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
1837762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1838762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1839762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
18403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1841a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1842a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1843e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1844e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1845e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1846e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1847e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
184821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
1849af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1850af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1851af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1852af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1853e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1854e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1855e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1856e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1857e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
185892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
185992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
186092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
186192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
186221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
1863af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1864af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1865af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
186692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
186792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
186892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
186992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
187092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1871580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
18720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
187321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
1874580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1875580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
18760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
18770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
18780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
18790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
18800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
18817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
188221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
18837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
18847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
18857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
18867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
18877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
18887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1889293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1890293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
189121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
1892293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1893293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1894293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1895293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1896293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1897293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1898293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
18997729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
19005fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1901cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
190221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
19030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1904d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
190521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
1906d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
1907275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
190821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
19090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
19100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
19115fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
19127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
191324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1914cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1915cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1916cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
19178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
19188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
19198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
1920862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
1921862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach                                      SMLoc S, SMLoc E) {
1922862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
1923862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
1924862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
1925862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
1926862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
1927862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
1928862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1929862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
193098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
193198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                              SMLoc S, SMLoc E) {
193298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
193398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.RegNum = RegNum;
193498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->VectorList.Count = Count;
193598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->StartLoc = S;
193698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Op->EndLoc = E;
193798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return Op;
193898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
193998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
19407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  static ARMOperand *CreateVectorListIndexed(unsigned RegNum, unsigned Count,
19417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                             unsigned Index, SMLoc S, SMLoc E) {
19427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorListIndexed);
19437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.RegNum = RegNum;
19447636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.Count = Count;
19457636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->VectorList.LaneIndex = Index;
19467636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->StartLoc = S;
19477636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Op->EndLoc = E;
19487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return Op;
19497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
19507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
1951460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1952460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
1953460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
1954460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
1955460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
1956460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
1957460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
1958460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1959460a90540b045c102012da2492999557e6840526Jim Grosbach
19603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
196121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
1962762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1963762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1964762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
19653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1966cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1967cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
19689d39036f62674606565217a10db28171b9594bc7Jim Grosbach  static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
196921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_FPImmediate);
19709d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->FPImm.Val = Val;
19719d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->StartLoc = S;
19729d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->EndLoc = S;
19739d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return Op;
19749d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
19759d39036f62674606565217a10db28171b9594bc7Jim Grosbach
19767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
19777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
19787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
19797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
19800d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
198157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
19827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
19833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
198421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
1985e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
1986e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
1987e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
1988e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
1989e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
199057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
1991e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
19927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
19937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
19947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
19957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
199616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1997f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1998f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
1999f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
20007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
200121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
20027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
2003f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
2004f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
2005f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
2006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
2007762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
20083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
2009a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2010706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2011706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
201221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
2013706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
2014706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
2015706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
2016706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
2017706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
2018a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2019a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
202021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
2021a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
2022a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
2023a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
2024a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
2025a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2026584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2027584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
202821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
2029584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
2030584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
2031584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
2032584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
2033584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
2034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
2035a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2036a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
2037a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2038b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
2039fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
204021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_FPImmediate:
20419d39036f62674606565217a10db28171b9594bc7Jim Grosbach    OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm())
20429d39036f62674606565217a10db28171b9594bc7Jim Grosbach       << ") >";
20439d39036f62674606565217a10db28171b9594bc7Jim Grosbach    break;
204421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
20456a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
2046fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
204721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
2048d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
2049d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
205021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
20511a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    static const char *MaskStr[] = {
20521a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "()", "(t)", "(e)", "(tt)", "(et)", "(te)", "(ee)", "(ttt)", "(ett)",
20531a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer      "(tet)", "(eet)", "(tte)", "(ete)", "(tee)", "(eee)"
20541a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer    };
205589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
205689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
205789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
205889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
205921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
2060fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
2061fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
206221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
2063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
2064fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
20659b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
20669b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
20679b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
206821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
2069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
2070584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
207121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
2072fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
2073fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
207421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
2075706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
2076706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
207721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
20786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
2079e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
20806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
2081fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
208221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
2083f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
2084f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
2085f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
2086f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
2087f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
2088f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
20897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
209021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
2091a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
2092a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
2093a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
2094a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
2095a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
2096a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
2097a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
2098a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
209921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
210050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
2101fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
210221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
2103580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
2104580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
2105e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
210621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
210792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
2108efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedReg.SrcReg << " "
2109efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedReg.ShiftTy)
2110efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " " << RegShiftedReg.ShiftReg << ">";
21110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
211221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
211392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
2114efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << RegShiftedImm.SrcReg << " "
2115efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << ARM_AM::getShiftOpcStr(RegShiftedImm.ShiftTy)
2116efed3d1f58f69ec0a9bbe74e2ce5cc9b939a3805Jim Grosbach       << " #" << RegShiftedImm.ShiftImm << ">";
211792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
211821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
21197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
21207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
212121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
2122293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
2123293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
2124293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
212521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
212621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
212721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
21288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
21298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
21305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
21315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
21327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
21337729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
21347729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
21358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
21368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
21378d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
21388d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
21398d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2140862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
2141862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
2142862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
2143862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
214498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case k_VectorListAllLanes:
214598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    OS << "<vector_list(all lanes) " << VectorList.Count << " * "
214698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach       << VectorList.RegNum << ">";
214798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
21487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case k_VectorListIndexed:
21497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    OS << "<vector_list(lane " << VectorList.LaneIndex << ") "
21507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach       << VectorList.Count << " * " << VectorList.RegNum << ">";
21517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
215221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
2153fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
2154fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
2155460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
2156460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
2157460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
2158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
2159fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
21603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
21613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
21623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
21633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
21643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
21653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
21663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
21673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
216869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
216969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
21701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
2171bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
2172bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
2173bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
2174bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
21759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
2176e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
2177e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
21783a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
21791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
218018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
21817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2182d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2183590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
21840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
21850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
21860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
21870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
21880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
21890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
21900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
219140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      // Additional register name aliases for 'gas' compatibility.
219240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a1", ARM::R0)
219340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a2", ARM::R1)
219440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a3", ARM::R2)
219540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("a4", ARM::R3)
219640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v1", ARM::R4)
219740e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v2", ARM::R5)
219840e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v3", ARM::R6)
219940e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v4", ARM::R7)
220040e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v5", ARM::R8)
220140e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v6", ARM::R9)
220240e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v7", ARM::R10)
220340e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("v8", ARM::R11)
220440e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sb", ARM::R9)
220540e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("sl", ARM::R10)
220640e285554773c51f6dd6eb8d076256e557fab9c3Jim Grosbach      .Case("fp", ARM::R11)
22070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
22080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
22090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
221069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2211b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2212460a90540b045c102012da2492999557e6840526Jim Grosbach
2213e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2214e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2215d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
221619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
221719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
221819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
221919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
222019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
22210d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
22220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
22240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
22250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
22260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2227590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string lowerCase = Tok.getString().lower();
22280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
2229af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      .Case("asl", ARM_AM::lsl)
22300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
22310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
22320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
22330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
22340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
22350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
22360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
22370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
223819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
22390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2245eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2249e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2250e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2251e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2253e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2255e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2256e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2257e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
22588a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().is(AsmToken::Hash) ||
22598a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        Parser.getTok().is(AsmToken::Dollar)) {
2260e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2262e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
226319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
226419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
226519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
226619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2267e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2268e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
226919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
227019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
227119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
227219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2273e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2274e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2275e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2277e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
228019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
228119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
22841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
228619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
228719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
228819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
228919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
229019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
229119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2292e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
229319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
229419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2295e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2296e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
229792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
229892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2299af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
23000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
230192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
230292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
230392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
23040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
230519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
23060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
23070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
23080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
230950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
231050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
231150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2312e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2313e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2314e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
231550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
23161355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2317e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
23181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2319e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
232050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2321d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
232250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2324e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2325e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
232650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
232750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2328e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2329460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2330460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2331460a90540b045c102012da2492999557e6840526Jim Grosbach
2332460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2333460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2334460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2335460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2336460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2337460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2338460a90540b045c102012da2492999557e6840526Jim Grosbach
2339460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2340460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
2341460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2342460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2343460a90540b045c102012da2492999557e6840526Jim Grosbach    if (!MCE) {
2344460a90540b045c102012da2492999557e6840526Jim Grosbach      TokError("immediate value expected for vector index");
2345460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2346460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2347460a90540b045c102012da2492999557e6840526Jim Grosbach
2348460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2349460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2350460a90540b045c102012da2492999557e6840526Jim Grosbach      Error(E, "']' expected");
2351460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2352460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2353460a90540b045c102012da2492999557e6840526Jim Grosbach
2354460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2355460a90540b045c102012da2492999557e6840526Jim Grosbach
2356460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2357460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2358460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
235999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
236099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
236150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2362a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2368e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2370e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
2371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
2372e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2374e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2375e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2376e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2377e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2378e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2379e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2380e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2381e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2382e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2383e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2384e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2385e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2386e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2387e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2388e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
2389e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2390fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2391e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2392e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2393e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2394e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2395e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2396e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2397e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2398e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2399e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2400e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2401e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
2402e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2403e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2404e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
2405e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2406e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
240789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
240889df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
240989df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
241089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
241189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
241289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
241389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
241489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
241589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
241689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
241789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
241889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
241989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
242089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
242189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
242289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
242389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
242489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
242589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
242689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
242789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
242889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
242989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
243089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
243189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
243289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
243389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
243489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
243589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
243689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
243789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
243889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
243989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
244089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
244189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
244243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2443fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2444fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2445f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
244643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2447e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2448e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2449c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2450c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2451e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2452fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2453e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2454f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2455e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2456e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2457fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2458f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2459fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2460fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
246143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2462fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2463fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2464f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
246543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2467fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2468c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2469c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2471fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2472fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2473f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2474fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2475fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2476fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2477f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2478e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2479e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
24809b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
24819b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
24829b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
24839b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
24859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
24869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
24879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
24889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
24899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
24909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
24919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
24929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
24939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
24949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
24959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
24969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
24979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
24989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
24999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
25009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
25019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
25029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
25039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
25049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
25059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
25069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
25079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
25089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
25099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
25109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
25119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
25129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
25139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2514d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2515d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2516d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2517d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2518d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2519d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2520d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2521d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2522d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2523d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2524d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
2525d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2526d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2527d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2528d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2529d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2530d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2531d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2532d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2533d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2534d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2535d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2536ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach// Return the low-subreg of a given Q register.
2537ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbachstatic unsigned getDRegFromQReg(unsigned QReg) {
2538ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  switch (QReg) {
2539ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  default: llvm_unreachable("expected a Q register!");
2540ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q0:  return ARM::D0;
2541ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q1:  return ARM::D2;
2542ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q2:  return ARM::D4;
2543ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q3:  return ARM::D6;
2544ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q4:  return ARM::D8;
2545ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q5:  return ARM::D10;
2546ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q6:  return ARM::D12;
2547ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q7:  return ARM::D14;
2548ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q8:  return ARM::D16;
254925e0a87e9190cdca62aee5ac95cfc8ef44f35e92Jim Grosbach  case ARM::Q9:  return ARM::D18;
2550ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q10: return ARM::D20;
2551ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q11: return ARM::D22;
2552ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q12: return ARM::D24;
2553ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q13: return ARM::D26;
2554ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q14: return ARM::D28;
2555ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  case ARM::Q15: return ARM::D30;
2556ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
2557ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach}
2558ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2559d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
256050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
25611355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
256218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2563a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2564e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2565d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2566d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
256716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2568d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2569d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2570d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2571d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2572d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2573d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2574ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2575ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // space for that many.
2576ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2577ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach
2578ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Allow Q regs and just interpret them as the two D sub-registers.
2579ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2580ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Reg = getDRegFromQReg(Reg);
2581ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2582ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    ++Reg;
2583ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  }
25841a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCRegisterClass *RC;
2585d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2586d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2587d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2588d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2589d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2590d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2591d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2592d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2593e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2594ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach  // Store the register.
2595d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2596d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2597d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2598d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2599d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2600d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2601d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2602d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2603e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2604d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2605d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2606d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2607d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2608ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2609ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2610ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2611d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2612d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2613d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2614d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2615d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2616d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2617d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2618d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2619d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2620d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2621d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2622d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2623d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2624d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2625d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2626d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2627d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2628d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2629d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2630d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2631d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2632a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    const AsmToken RegTok = Parser.getTok();
2633d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2634d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
26352d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2636ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    // Allow Q regs and just interpret them as the two D sub-registers.
2637ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    bool isQReg = false;
2638ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2639ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Reg = getDRegFromQReg(Reg);
2640ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      isQReg = true;
2641ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    }
2642d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2643d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2644d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2645d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2646a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) < getARMRegisterNumbering(OldReg))
2647d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2648a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    if (getARMRegisterNumbering(Reg) == getARMRegisterNumbering(OldReg)) {
2649a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      Warning(RegLoc, "duplicated register (" + RegTok.getString() +
2650a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach              ") in register list");
2651a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach      continue;
2652a62d11ea942ab99ba74589f74d390138654b6197Jim Grosbach    }
2653d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2654d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2655d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2656d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2657d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2658d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2659d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2660ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach    if (isQReg)
2661ce485e7f70faed6d19daafff91bb20509403d432Jim Grosbach      Registers.push_back(std::pair<unsigned, SMLoc>(++Reg, RegLoc));
2662d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2663d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2664d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2665d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2666d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2667d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2668e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
266950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
267050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2671d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2672d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
267398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach// Helper function to parse the lane index for vector lists.
267498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
26757636bf6530fd83bf7356ae3894246a4e558741a4Jim GrosbachparseVectorLane(VectorLaneTy &LaneKind, unsigned &Index) {
26767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  Index = 0; // Always return a defined index value.
267798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
267898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Parser.Lex(); // Eat the '['.
267998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    if (Parser.getTok().is(AsmToken::RBrac)) {
268098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // "Dn[]" is the 'all lanes' syntax.
268198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      LaneKind = AllLanes;
268298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Parser.Lex(); // Eat the ']'.
268398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_Success;
268498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
26857636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (Parser.getTok().is(AsmToken::Integer)) {
26867636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      int64_t Val = Parser.getTok().getIntVal();
26877636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      // Make this range check context sensitive for .8, .16, .32.
26887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (Val < 0 && Val > 7)
26897636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Error(Parser.getTok().getLoc(), "lane index out of range");
26907636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      Index = Val;
26917636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      LaneKind = IndexedLane;
26927636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      Parser.Lex(); // Eat the token;
26937636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (Parser.getTok().isNot(AsmToken::RBrac))
26947636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Error(Parser.getTok().getLoc(), "']' expected");
26957636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      Parser.Lex(); // Eat the ']'.
26967636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      return MatchOperand_Success;
26977636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    }
26987636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Error(Parser.getTok().getLoc(), "lane index must be empty or an integer");
269998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
270098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
270198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  LaneKind = NoLanes;
270298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  return MatchOperand_Success;
270398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach}
270498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach
2705862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2706862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2707862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
270898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  VectorLaneTy LaneKind;
27097636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  unsigned LaneIndex;
27105c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
27115c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // As an extension (to match gas), support a plain D register or Q register
27125c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // (without encosing curly braces) as a single or double entry list,
27135c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  // respectively.
27145c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().is(AsmToken::Identifier)) {
27155c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    int Reg = tryParseRegister();
27165c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (Reg == -1)
27175c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_NoMatch;
27185c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    SMLoc E = Parser.getTok().getLoc();
27195c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
27207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
272198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
272298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
272398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
272498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      default:
272598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        assert(0 && "unexpected lane kind!");
272698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
272798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
272898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E));
272998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
273098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
273198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
273298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, S, E));
273398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
27347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
27357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 1,
27367636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                                               LaneIndex, S,E));
27377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
273898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
27395c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
27405c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
27415c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
27425c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      Reg = getDRegFromQReg(Reg);
27437636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      OperandMatchResultTy Res = parseVectorLane(LaneKind, LaneIndex);
274498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      if (Res != MatchOperand_Success)
274598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return Res;
274698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      switch (LaneKind) {
274798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      default:
274898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        assert(0 && "unexpected lane kind!");
274998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case NoLanes:
275098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
275198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E));
275298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
275398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      case AllLanes:
275498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        E = Parser.getTok().getLoc();
275598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, S, E));
275698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        break;
27577636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      case IndexedLane:
27587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        Operands.push_back(ARMOperand::CreateVectorListIndexed(Reg, 2,
27597636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                                               LaneIndex, S,E));
27607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach        break;
276198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
27625c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach      return MatchOperand_Success;
27635c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    }
27645c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    Error(S, "vector register expected");
27655c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach    return MatchOperand_ParseFail;
27665c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  }
27675c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach
27685c984e451d604e3ff3cfdc5db7c0b6ca6be7a14fJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
2769862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
2770862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2771862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
2772862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
2773862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2774862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
2775862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
2776862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
2777862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2778862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2779862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
2780c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  unsigned FirstReg = Reg;
2781c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // The list is of D registers, but we also allow Q regs and just interpret
2782c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  // them as the two D sub-registers.
2783c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2784c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    FirstReg = Reg = getDRegFromQReg(Reg);
2785c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Reg;
2786c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    ++Count;
2787c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach  }
27887636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  if (parseVectorLane(LaneKind, LaneIndex) != MatchOperand_Success)
278998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    return MatchOperand_ParseFail;
2790c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach
2791e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2792e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2793e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2794e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Parser.Lex(); // Eat the minus.
2795e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2796e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      int EndReg = tryParseRegister();
2797e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (EndReg == -1) {
2798e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "register expected");
2799e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2800e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
2801e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Allow Q regs and just interpret them as the two D sub-registers.
2802e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(EndReg))
2803e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        EndReg = getDRegFromQReg(EndReg) + 1;
2804e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // If the register is the same as the start reg, there's nothing
2805e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // more to do.
2806e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg == EndReg)
2807e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        continue;
2808e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // The register must be in the same register class as the first.
2809e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (!ARMMCRegisterClasses[ARM::DPRRegClassID].contains(EndReg)) {
2810e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "invalid register in register list");
2811e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2812e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
2813e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Ranges must go from low to high.
2814e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      if (Reg > EndReg) {
2815e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        Error(EndLoc, "bad range in register list");
2816e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach        return MatchOperand_ParseFail;
2817e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      }
281898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
281998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
28207636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
28217636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
282298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
28237636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
282498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
282598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
282698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
282798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      EndLoc = Parser.getTok().getLoc();
2828e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach
2829e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      // Add all the registers in the range to the register list.
2830e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Count += EndReg - Reg;
2831e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      Reg = EndReg;
2832e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach      continue;
2833e43862b6a6130ec29ee4e9e6c6c30b5607c9a728Jim Grosbach    }
2834862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
2835862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
2836862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
2837862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
2838862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
2839862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
2840862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
2841862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
2842c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // vector register lists must be contiguous.
2843862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2844862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
2845c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    //
2846c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // The list is of D registers, but we also allow Q regs and just interpret
2847c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // them as the two D sub-registers.
2848c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
2849c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Reg = getDRegFromQReg(Reg);
2850c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      if (Reg != OldReg + 1) {
2851c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        Error(RegLoc, "non-contiguous register range");
2852c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach        return MatchOperand_ParseFail;
2853c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      }
2854c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      ++Reg;
2855c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      Count += 2;
285698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      // Parse the lane specifier if present.
285798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      VectorLaneTy NextLaneKind;
28587636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      unsigned NextLaneIndex;
285998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
28607636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
286198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
28627636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach      if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
286398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        Error(EndLoc, "mismatched lane index in register list");
286498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach        return MatchOperand_ParseFail;
286598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      }
2866c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach      continue;
2867c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    }
2868c73d73eb881ebe7493e934c00ca1c474ffd0ed2dJim Grosbach    // Normal D register. Just check that it's contiguous and keep going.
2869862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg != OldReg + 1) {
2870862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
2871862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
2872862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
2873862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
287498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    // Parse the lane specifier if present.
287598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    VectorLaneTy NextLaneKind;
28767636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    unsigned NextLaneIndex;
287798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    SMLoc EndLoc = Parser.getTok().getLoc();
28787636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (parseVectorLane(NextLaneKind, NextLaneIndex) != MatchOperand_Success)
287998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
28807636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    if (NextLaneKind != LaneKind || LaneIndex != NextLaneIndex) {
288198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      Error(EndLoc, "mismatched lane index in register list");
288298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach      return MatchOperand_ParseFail;
288398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    }
2884862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2885862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2886862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2887862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
2888862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
2889862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2890862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2891862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
2892862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
289398b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  switch (LaneKind) {
289498b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  default:
289598b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    assert(0 && "unexpected lane kind in register list.");
289698b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case NoLanes:
289798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E));
289898b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
289998b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  case AllLanes:
290098b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
290198b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach                                                            S, E));
290298b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach    break;
29037636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  case IndexedLane:
29047636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorListIndexed(FirstReg, Count,
29057636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach                                                           LaneIndex, S, E));
29067636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    break;
290798b05a57b67d1968381563c8cccbbb6c6cb65e3dJim Grosbach  }
2908862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
2909862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
2910862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
291143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
2912f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
291343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2914706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2915706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2916706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2917706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
2918706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2919706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
2920706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
2921706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
2922032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
2923706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
2924032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
2925706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
2926706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
2927032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
2928706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
2929032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
2930706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
2931706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
2932706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
2933706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2934706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
2935f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2936706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2937706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2938706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
2939f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2940706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
2941706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
294243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
2943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
294443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2945a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2946a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2947a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2948a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
2949a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
29502dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
29512dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
2952a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
29532dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
29542dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
29552dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
29562dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
29572dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
29582dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
29592dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
29602dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
29612dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
29622dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
29632dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
29642dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
29652dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
29662dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
29672dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
2968a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2969a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2970a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2971a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
2972a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
2973584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
2974584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
297543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
2976584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
297743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2978584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2979584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2980584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2981584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
2982584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2983acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
2984acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
2985acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
2986acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
2987acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
2988acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
2989acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
2990acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
2991acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
2992acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
2993acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
2994acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
2995acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
2996acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
2997acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
2998acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
2999acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
3000acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
3001acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3002acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
3003acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3004acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3005acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
3006acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
3007acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
3008acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3009acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
3010acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3011acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
3012acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
3013acad68da50581de905a994ed3c6b9c197bcea687James Molloy
3014584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
3015584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
3016584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
3017590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string SpecReg = Mask.slice(Start, Next).lower();
3018584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
3019584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
3020584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3021584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
3022584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
3023584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3024584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
3025584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3026584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
3027584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
3028b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
3029584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
3030584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
3031584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
3032584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
30334b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
3034584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
3035584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3036584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
3037bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
30384b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
3039584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
304056926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
304156926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
3042584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
3043584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
3044584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
3045584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
3046584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
3047584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
3048584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
3049584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3050584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
3051584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
3052584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
3053584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
3054584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
3055584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
3056584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
3057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
3058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
30597784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
30607784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
30617784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
30627784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
30637784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
30647784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
30657784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
3066584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3067584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
3068584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
3069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
3070584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3071584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
3072584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
3073584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
3074a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
3075a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3076f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3077f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
3078f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
3079f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3080f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3081f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3082f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3083f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3084f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
3085590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string LowerOp = Op.lower();
3086590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer  std::string UpperOp = Op.upper();
3087f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
3088f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
3089f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3090f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3091f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
3092f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3093f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
30948a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
30958a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3096f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3097f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3098f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3099f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
3100f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3101f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
3102f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
3103f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3104f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
3105f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3106f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3107f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3108f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
3109f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
3110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3112f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
3113f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
3114f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
3115f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
3116f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
3117f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3118f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
3119f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3120f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
3121f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
3122f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
3123c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3124c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3125c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
3126c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
3127c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3128c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3129c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3130c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3131c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
3132c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
3133c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
3134c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
3135c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
3136c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3137c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
3138c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
3139c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
3140c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
3141c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
3142c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
3143c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
3144c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
3145c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
3146c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
3147580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
3148580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
3149580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
3150580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
3151580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
3152580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3153580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3154580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
3155580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
3156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
3157580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3158580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3159580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3160580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
3161580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
3162580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
3163580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
3164580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
3165580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
3166580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
3167580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
3168580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3169580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3170580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
3171580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3172580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
31738a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
31748a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3175580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3176580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3177580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3178580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
3179580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3180580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
3181580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
3182580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
3183580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
3184580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3185580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3186580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
3187580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
3188580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
3189580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
3190580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3191580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3192580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
3193580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
3194580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3195580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
3196580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
3197580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3198580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
31990afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
32000afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
32010afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
32020afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
32030afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
3204580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
3205580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
3206580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
3207580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
3208580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
3209580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
3210580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
3211580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
3212580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3213580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
3214580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
3215580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
3216580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
3217580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
3218580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
32197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
32207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
32217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
32227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
32237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
32247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
32257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
3226326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
3227326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
32287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
3229326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
3230326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
32317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
32327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
32337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
32348a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
32358a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
32367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
32377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
32387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
32397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
32407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
32417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
32427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
32437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
32447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
32457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
32467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
32477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
32487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
32497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
32507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
32517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
32527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
32537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
32547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
32557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
32567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
32577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
32587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
32597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
32607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
32617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
32627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
32637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
32647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
32657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
32667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
32677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
3268293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3269293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3270293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
3271293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
32728a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
32738a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3274293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3275293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3276293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3277293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3278293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3279293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
3280293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3281293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
3282293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3283293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3284293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3285293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
3286293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3287293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
3288293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3289293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3290293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3291293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
3292293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
3293293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
3294293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
3295293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3296293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3297293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3298293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3299293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
3300293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
3301293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
3302293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3303293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3304293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
33058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
33068a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar)) {
3307293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
3308293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3309293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3310293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
3311293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3312293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
3313293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
3314293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
3315293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3316293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3317293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
3318293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
3319293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
3320293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3321293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3322293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3323293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
3324293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
3325293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
3326293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
3327293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
3328293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
3329293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
3330293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3331293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
3332293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
3333293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
3334293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
3335293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
33367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
33377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
33387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3339f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
3340f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
3341f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
33427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
33437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
33447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
33457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
33467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
33477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
33487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
334916578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
33507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
33517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
33527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
33537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
33547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
33557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
335616578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
33577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
33587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
33597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
33607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
33617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
33627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
33637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
33647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
33657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
33667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
33677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
33687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3369f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
3370f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
33710d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
33720d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
33730d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
33740d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
33750d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
3376f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
3377f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
3378f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
33797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
33807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
33817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
33827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3383251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
3384251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3385251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
3386251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
3387251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
3388251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
3389251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
3390251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
3391251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
3392251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3393251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
3394251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
3395251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
3396251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
3397251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
3398251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3399251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
34008a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
34018a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar)) {
3402251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
3403251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
3404251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
3405251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3406251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
3407251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
3408251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3409251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
3410251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
3411251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
3412251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
3413251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
3414251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
3415251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
3416251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
3417251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
3418251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
3419251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3420251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
3421251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
3422251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3423251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
3424251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3425251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3426251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3427251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
3428251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
3429251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
3430251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
3431251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
3432251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3433251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
3434251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
3435251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
3436251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
3437251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3438251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3439251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3440251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3441251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3442251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3443251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3444251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3445251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3446251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3447251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3448251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3449251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3450251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3451251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3452251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3453251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3454a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3455a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3456a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3457a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3458a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3459a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3460a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3461a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3462a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3463a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3464a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3465a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3466a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3467a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3468a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3469a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3470a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3471a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3472a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3473a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3474a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3475a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3476a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3477a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3478a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3479a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3480a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3481a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3482a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3483a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3484a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3485a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3486a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3487a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3488a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3489a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3490eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3491eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3492eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3493eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3494eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3495eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3496eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3497eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3498eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3499eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3500eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3501eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3502eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3503eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3504eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3505eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3506ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3507ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3508ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3509ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3510ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3511ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3512ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3513ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3514ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3515ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3516ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3517ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3518ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3519ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
35201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3521ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3522ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3523ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
35241355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3525ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3526ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3527ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3528ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3529ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3530ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
35317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3532ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
35369ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
35379ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
35389ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
35399ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
35409ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
35419ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
35429ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
35439ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
35449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
35459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
35469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
35479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
35489ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
35499ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
35509ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
35519ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
35529ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3553548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3554548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3555548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3556548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3557548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3558548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3559548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3560548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3561548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3562548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3563548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3564548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3565548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3566548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
35671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3568ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3569ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3570ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
35711355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3572ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3573ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3574ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3575548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3576548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3577548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
35787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
35797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
35807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
35817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
35827b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
35837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
35847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
35857b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
35867b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
35877b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
35887b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
35897b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
35907b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
35917b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
35927b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
35937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
35947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
35957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
35967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
35977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
35987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
35997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
36007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3602ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
36047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
36057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
36067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
36077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
36087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
36097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
36147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3615ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3616ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3617ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
36187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
36197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3621aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3622ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3623ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
36247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
36257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
36267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
36277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
36287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
36297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
36307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
36317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3632aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
36337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
36347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
36357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
36367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
36377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
36387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
36407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
36417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
36427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
36447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
36457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
36467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
36477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
36527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3653ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3654ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3655ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
36567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
36577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
36607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
36637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
36647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
36657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
36667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
36712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
36722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
36732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
36742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
36752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
36762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
36772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
36782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
36792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
36802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
36812fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
36822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
36832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
36842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
36852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
36862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
36872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
36882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
368914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
369014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
369114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
369214605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
369314605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
369414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
369514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
369614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
369714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
369814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
369914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
370014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
370114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
370214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
370314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
370414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
370514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
370614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3707623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3708623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3709623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3710623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3711623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3712623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3713623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3714623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3715623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3716623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3717623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3718623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
3719623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
3720623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
372188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
372288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
372388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
372488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
372588ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
372688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
372788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
372888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
372988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
37307a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
37317a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
37327a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
37337a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
373488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
37357a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
373688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
373788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
373888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
373988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
37401b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // If we have a three-operand form, make sure to set Rn to be the operand
37411b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  // that isn't the same as Rd.
37421b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  unsigned RegOp = 4;
37431b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  if (Operands.size() == 6 &&
37441b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach      ((ARMOperand*)Operands[4])->getReg() ==
37451b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach        ((ARMOperand*)Operands[3])->getReg())
37461b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach    RegOp = 5;
37471b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  ((ARMOperand*)Operands[RegOp])->addRegOperands(Inst, 1);
37481b332860aef0121cf4591f4377a7201ce0ef8366Jim Grosbach  Inst.addOperand(Inst.getOperand(0));
374988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
375088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
375188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
375288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
3753623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
375412431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
375512431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbFixed(MCInst &Inst, unsigned Opcode,
375612431329d617064d6e72dd040a58c1635cc261abJim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
375712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
37586029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
375912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
376012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
376112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
376212431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
376312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
376412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
376512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
376612431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
376712431329d617064d6e72dd040a58c1635cc261abJim Grosbach
376812431329d617064d6e72dd040a58c1635cc261abJim Grosbachbool ARMAsmParser::
376912431329d617064d6e72dd040a58c1635cc261abJim GrosbachcvtVLDwbRegister(MCInst &Inst, unsigned Opcode,
377012431329d617064d6e72dd040a58c1635cc261abJim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
377112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vd
37726029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
377312431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Create a writeback register dummy placeholder.
377412431329d617064d6e72dd040a58c1635cc261abJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
377512431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vn
377612431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
377712431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // Vm
377812431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
377912431329d617064d6e72dd040a58c1635cc261abJim Grosbach  // pred
378012431329d617064d6e72dd040a58c1635cc261abJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
378112431329d617064d6e72dd040a58c1635cc261abJim Grosbach  return true;
378212431329d617064d6e72dd040a58c1635cc261abJim Grosbach}
378312431329d617064d6e72dd040a58c1635cc261abJim Grosbach
37844334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
37854334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbFixed(MCInst &Inst, unsigned Opcode,
37864334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach              const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
37874334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
37884334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
37894334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
37904334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
37914334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
37926029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
37934334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
37944334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
37954334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
37964334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
37974334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
37984334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbachbool ARMAsmParser::
37994334e032525d6c9038605f3871b945e8cbe6fab7Jim GrosbachcvtVSTwbRegister(MCInst &Inst, unsigned Opcode,
38004334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach                 const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
38014334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Create a writeback register dummy placeholder.
38024334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
38034334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vn
38044334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[4])->addAlignedMemoryOperands(Inst, 2);
38054334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vm
38064334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
38074334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // Vt
38086029b6ddafad45791c9e9d8e8ddd96978294beefJim Grosbach  ((ARMOperand*)Operands[3])->addVecListOperands(Inst, 1);
38094334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  // pred
38104334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
38114334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach  return true;
38124334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach}
38134334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach
3814e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
38159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
381650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
38177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3818762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
381918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
3820a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
3821762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
3822b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
3823a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
382418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
38251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
38267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
38277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
3828a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
38290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
38300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
38310571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
38327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
38330571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
38347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
3835762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
3836b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
3837a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
38387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
383957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
384003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
3841fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
3842fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
3843fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
3844fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3845fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
3846fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
3847fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
38487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
38497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
385050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
38517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
38527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
385350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
385457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
385557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
385657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
385757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
385857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
385957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
386057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
386157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
386257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
386357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
386457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
386557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
386657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
386757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
386857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
386957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
387057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
387157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
387257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
387357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "alignment specifier must be 64, 128, or 256 bits");
387457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
387557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
387657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
387757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
387857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
387957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
388057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
388157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
388257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
388357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
388457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
388557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
388657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
388757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
388857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
388957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
389057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
389157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
389257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
389357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
389457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
389557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
389657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
389757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
389857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
389957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
390057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
390157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
39026cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // offset. Be friendly and also accept a plain integer (without a leading
39036cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  // hash) for gas compatibility.
39046cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash) ||
39058a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().is(AsmToken::Dollar) ||
39066cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.getTok().is(AsmToken::Integer)) {
39078a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (Parser.getTok().isNot(AsmToken::Integer))
39086cb4b081829880ba97a729bcf33fd59517ca5450Jim Grosbach      Parser.Lex(); // Eat the '#'.
39097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
391050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
39110da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
39127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
39137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
39147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
391505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
39167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
39177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
39187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
39197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
39207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
39217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
39227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
39230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
39240da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
39250da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
39260da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
39270da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
39287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
39297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
39307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
39317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
39327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
393305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
39347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
39357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
39367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
393757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
393857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
3939a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
39407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
39417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
39427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
39437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
39447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
3945762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
39467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
39477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
39489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
3949d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
39507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
39517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
39527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
39537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
39547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
39557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
39567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
39577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
39587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
39599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
39607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
39617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
39627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
39637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
39647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
39657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
39667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
39670d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
39687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
39697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
39700d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
39717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
39729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
397316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
39747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
39757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
39767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
39777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
39787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
39797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
39807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
398157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
39827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
39837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3984f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
3985f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
3986f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
3987f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3988f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
3989f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
39909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
39919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
39929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
39939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
39947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
3995a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
3996a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
39977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
39987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
39997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
40007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
400118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4002a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4003a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
400438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
4005af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL" ||
4006af4edea67b007592f9474e07d27182956e37f7f5Jim Grosbach      ShiftName == "asl" || ShiftName == "ASL")
40070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
4008a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
40090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
4010a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
40110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
4012a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
40130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
4014a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
40150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
4016a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
40177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
4018b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
4019a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
40217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
40227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
40237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
40247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
40257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
40268a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach    if (HashTok.isNot(AsmToken::Hash) &&
40278a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach        HashTok.isNot(AsmToken::Dollar))
40287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
40297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
40309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
40317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
40327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
40337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
40347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
40357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
40367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
40377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
40387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
40397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
40407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
40417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
40427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
40437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
40447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
40457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
40467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
4047a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4048a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
4049a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4050a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40519d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
40529d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
40539d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
40549d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
40559d39036f62674606565217a10db28171b9594bc7Jim Grosbach
40568a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash) &&
40578a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach      Parser.getTok().isNot(AsmToken::Dollar))
40589d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
40590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
40600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
40610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
40620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
40630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
40640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
40650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
40660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
40670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
40680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
40690e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
40700e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
40710e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
40720e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
40730e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
40740e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
40759d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
40769d39036f62674606565217a10db28171b9594bc7Jim Grosbach
40779d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
40789d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
40799d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
40809d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
40819d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
40829d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
40839d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
40849d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
40859d39036f62674606565217a10db28171b9594bc7Jim Grosbach    APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
40869d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
40879d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
40889d39036f62674606565217a10db28171b9594bc7Jim Grosbach    IntVal ^= (uint64_t)isNegative << 63;
40899d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int Val = ARM_AM::getFP64Imm(APInt(64, IntVal));
40909d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
40919d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val == -1) {
40929d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("floating point value out of range");
40939d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
40949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
40959d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
40969d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
40979d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
40989d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
40999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
41009d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
41019d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
41029d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("encoded floating point value out of range");
41039d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
41049d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
41059d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
41069d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
41079d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
41089d39036f62674606565217a10db28171b9594bc7Jim Grosbach
41099d39036f62674606565217a10db28171b9594bc7Jim Grosbach  TokError("invalid floating point immediate");
41109d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
41119d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
41129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
41139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
41141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4115fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
4116762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
4117fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4118fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
4119fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
4120f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4121f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
4122fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
4123f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4124f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
4125f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
4126f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
4127f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
4128fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
4129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
4130146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
4131146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
413250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
413319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
41345cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
41351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
413650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
41370d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
413819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
41390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
414019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
414119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
41425cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
41435cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
41445cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
41455cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
41465cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
41475cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
4148e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
4149e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
4150e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
415119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
4152758a519a22b469ce8e2b8d0bf7a72813e87710d4Jim Grosbach  case AsmToken::LParen:  // parenthesized expressions like (_strcmp-4)
415367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
41546284afc293c8f6e84dffab8731aa9e679d437745Jim Grosbach  case AsmToken::String:  // quoted label names.
415567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
4156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
4157515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
4158515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
4159762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4160515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
416150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
4162762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
416350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
416450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
416550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
4166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
41671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
4168d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
41691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
41708a12e3b5df13b279eff3cfc29e0d7808ff86aa44Jim Grosbach  case AsmToken::Dollar:
417163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
4172079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
4173079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
4174762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
4175b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
417663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
4177515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
4178515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
417950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
418063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
4181ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach    if (CE) {
4182ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      int32_t Val = CE->getValue();
4183ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach      if (isNegative && Val == 0)
4184ed6a0c5243f4dc13169edc8e342c679f1bfc201cJim Grosbach        ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
418563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
4186762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
418750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
418850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
418963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
41909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
41919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
41927597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
41937597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
41947597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
41951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
41969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
41979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
41987597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
41997597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
42009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
42019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42027597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
42037597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
42049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
42057597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
42069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
42079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
4208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
4209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
4210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
42111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
42127597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
42131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
42147597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
42159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
42178a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
42189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
42199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
42219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
42229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
42239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
42249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
42269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
42277597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
42289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
42297597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
42309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
42319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
42329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
42339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
42349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
42359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
42369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
42379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
42389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
42399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
42409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
42419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
42429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
42439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
4244352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
4245352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
4246352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
4247badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
424889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
42491355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
42505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
42515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
425289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
425389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
4254352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
4255352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
4256a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
4257352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4258badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
4259352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
4260352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
42615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
42625f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
42635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
42645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
42655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
42665f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
42675f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
42685f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
4269352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
4270badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
42713f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
42723f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
4273ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
427471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
427504d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
42762f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
42773f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
42783f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
42793f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
42803f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
42813f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
42823f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
42833f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
42843f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
42853f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
42863f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
42873f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
42883f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
42893f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
42903f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
42913f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
42923f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
42933f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
42943f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
42953f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
42963f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
42973f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
42983f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
42993f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
430052925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
4301345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4302352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
4303352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
4304352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
430500f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
43065f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
43075f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
43085f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
430967ca1adf822c6cbc2f2bb78b8f94eefd099a8eb6Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" || Mnemonic == "flds" ||
431048171e7fbe58bb418f09717813779d03903d35e4Jim Grosbach        Mnemonic == "fmrs" || Mnemonic == "fsqrts" || Mnemonic == "fsubs" ||
4311f10154010ec01a6965f86e8c136db79732c92eeeJim Grosbach        Mnemonic == "fsts" ||
4312e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
4313352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
4314352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
4315352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
4316352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
4317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
4318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
4319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
4320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
4321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
4322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
4323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
4324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
4325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
4326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
4327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
4328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
4329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
4330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
433289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
433389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
433489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
433589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
433689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
433789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4338352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
4339352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
43403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
43413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
43423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
43433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
43443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
4345fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
43461355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
4347fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
4348eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
4349eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
43503443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
4351eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
4352d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
4353eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
4354d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
43553443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
4356d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
4357d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
4358eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
4359fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
4360eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
43613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
4362eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
4363eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
4364eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
4365eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
4366ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
4367ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
43680780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
43692bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
43702bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
43712bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
43724af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
43734af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
43741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
43753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
4376fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
43773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
4378fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
4379fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
4380fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
438163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
4382fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
4383fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
4384badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
4385badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4386d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
4387d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
438820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
438920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
4390d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
4391d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
4392d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
4393d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
4394d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
4395d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
4396d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
4397d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
4398d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
43998adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
4400d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
4401d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
4402d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
4403d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
44043912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
44053912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
44063912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
44073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
44083912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
44093912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
44103912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
44113912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
441272f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
441320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
441420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
441520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
4416f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
4417f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
4418f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
441972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
442072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
442172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
442220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
442320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
442420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
442572f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
4426f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
4427f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
442820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
442920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
443020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
4431f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
4432f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
443320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
443420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
443520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
443620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
443720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
443820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
443920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
444020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // check against T3.
444120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
444220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
444320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
444420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
444520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
444620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
444720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
444864944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
444920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
445020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
445120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
445220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
445320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
445420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
445520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
445620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
445720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
445864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
445964944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
446064944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
446164944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
446264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
446364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
446464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
446564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
446664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
446764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
446864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
446964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
447064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
447164944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
44721de0bd194540f8bab399fb39c4ba615a7b2381d3Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[5])->getReg()) ||
447364944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
447464944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
447564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
447664944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
447764944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
447864944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
447964944f48a1164c02c15ca423a53919682a89074cJim Grosbach
44807f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // Also check the 'mul' syntax variant that doesn't specify an explicit
44817f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  // destination register.
44827f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 5 &&
44837f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
44847f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
44857f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
44867f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // If the registers aren't low regs  or the cc_out operand is zero
44877f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
44887f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      // remove the cc_out operand.
44897f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
44907f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
44917f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach       !inITBlock()))
44927f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach    return true;
44937f1ec9570d673aedd13c5621407085400bab8299Jim Grosbach
449464944f48a1164c02c15ca423a53919682a89074cJim Grosbach
449520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
4496f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
4497f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
4498f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
4499f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
4500f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
4501f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
4502f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
450372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
450472f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
450572f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
450672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
45073912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
4508d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
4509d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
4510d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
45117aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool isDataTypeToken(StringRef Tok) {
45127aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Tok == ".8" || Tok == ".16" || Tok == ".32" || Tok == ".64" ||
45137aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".i8" || Tok == ".i16" || Tok == ".i32" || Tok == ".i64" ||
45147aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".u8" || Tok == ".u16" || Tok == ".u32" || Tok == ".u64" ||
45157aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".s8" || Tok == ".s16" || Tok == ".s32" || Tok == ".s64" ||
45167aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".p8" || Tok == ".p16" || Tok == ".f32" || Tok == ".f64" ||
45177aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    Tok == ".f" || Tok == ".d";
45187aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
45197aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
45207aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// FIXME: This bit should probably be handled via an explicit match class
45217aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// in the .td files that matches the suffix instead of having it be
45227aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach// a literal string token the way it is now.
45237aef99b677452724100145c81f76f32e494cc5a7Jim Grosbachstatic bool doesIgnoreDataTypeSuffix(StringRef Mnemonic, StringRef DT) {
45247aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach  return Mnemonic.startswith("vldm") || Mnemonic.startswith("vstm");
45257aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach}
45267aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
452721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbachstatic void applyMnemonicAliases(StringRef &Mnemonic, unsigned Features);
4528badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
4529badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
4530badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
453121d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // Apply mnemonic aliases before doing anything else, as the destination
453221d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // mnemnonic may include suffices and we want to handle them normally.
453321d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // The generic tblgen'erated code does this later, at the start of
453421d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // MatchInstructionImpl(), but that's too late for aliases that include
453521d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  // any sort of suffix.
453621d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  unsigned AvailableFeatures = getAvailableFeatures();
453721d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach  applyMnemonicAliases(Name, AvailableFeatures);
453821d7fb814adcedc7b2f156e003d2083ad1d8ac6aJim Grosbach
4539badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
4540badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
4541ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
4542badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
4543352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
4544352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
4545a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
4546352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
454789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
45481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
454989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4550badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
45510c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
45520c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
45530c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
45540c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
45550c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
45560c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4557ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4558ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
455989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
456089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
456189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
456289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
456389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
456489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4565f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4566f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4567f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4568f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4569f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
457089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
457189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
457289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
457389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
457489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4575f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
457689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
457789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
457889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
457989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
458089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4581f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
458289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
458389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4584ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4585ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
45869717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
45873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
45883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
45893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
45903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
45913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
45923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
45933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
45943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
45951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
45963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
459733c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
459833c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
459933c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
460033c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4601ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
460233c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
460333c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4604c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4605c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4606c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4607c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4608c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4609c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4610c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
461133c16a27370939de39679245c3dff72383c210bdJim Grosbach
46123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4613f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4614f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
46153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4616f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4617f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
46183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
46193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
46203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4621f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4622f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
46233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4624f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4625badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4626345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4627a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4628a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4629a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4630a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4631a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4632a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4633a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4634345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
46355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
46365747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
46375747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4638a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4639a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
46407aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // Some NEON instructions have an optional datatype suffix that is
46417aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    // completely ignored. Check for that.
46427aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach    if (isDataTypeToken(ExtraToken) &&
46437aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach        doesIgnoreDataTypeSuffix(Mnemonic, ExtraToken))
46447aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach      continue;
46457aef99b677452724100145c81f76f32e494cc5a7Jim Grosbach
464681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
464781d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
464881d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
464981d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
46505747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
46515747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
46525747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
46535747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4654a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
46551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4656cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4657cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4658cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4660a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4661b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4662a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4663a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
46641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4665cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4666cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4667cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4668a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4669a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
467016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4671cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4672186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4673cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4674186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4675cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4676146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
467734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4678ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4679d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4680d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4681d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
468220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
468320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
468420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
468520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
468620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4687ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4688ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
4689ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
4690ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
4691ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4692cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
4693cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
4694cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
469521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
469621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
4697cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
4698cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
4699cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4700cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
4701cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
4702cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
4703857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
4704857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
4705857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
4706857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
4707857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
4708857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
4709857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4710857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4711857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4712857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
4713857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
4714857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
471568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
471668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
471768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
471868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
471968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
472068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
472168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
472268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
472368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
472468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
472568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4726857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
4727857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
4728857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
4729934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
473055b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // end. Convert it to a token here. Take care not to convert those
473155b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach  // that should hit the Thumb2 encoding.
4732934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
473355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
473455b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
4735934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4736934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4737934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
473855b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach    if (CE && CE->getValue() == 0 &&
473955b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach        (isThumbOne() ||
4740d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // The cc_out operand matches the IT block.
4741d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         ((inITBlock() != CarrySetting) &&
4742d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach         // Neither register operand is a high register.
474355b02f28c1a2960ebb88cf5019cc5b36bb2eabf4Jim Grosbach         (isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
4744d7ea73a4909fc3200a1cecd2b420d7ace2180b70Jim Grosbach          isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()))))){
4745934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
4746934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4747934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
4748934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
4749934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
4750934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
47519898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
4752ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4753ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4754189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
4755aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
4756aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
4757aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
4758aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
4759aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
4760aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
4761aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
4762aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
4763aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
4764aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
4765aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
4766aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
4767aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
4768aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
4769aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
4770aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
4771aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
4772aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
477376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
477476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
477576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
477676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
477776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
477876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
477976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
478076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
478176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
478276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
478376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
4784f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
4785f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
4786f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
4787f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
47881a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
4789f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
47901a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
4791f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
4792f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
4793f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4794189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
4795189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
4796189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
4797189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
47981a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
4799f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
4800f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
4801b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
4802b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // being allowed in IT blocks, but not being predicable.  It just always
4803b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
4804b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
4805f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
4806f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
4807f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
4808f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
4809a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
4810f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
4811f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
4812f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
4813f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
4814f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
4815f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
4816f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
4817f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
4818f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
4819f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
4820f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
4821f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
4822f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
4823f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
4824f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
4825f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
4826f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
4827c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
4828f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
4829f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
483051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
483151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
4832f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
4833f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4834189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
48352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
48362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
48372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
4838189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
4839189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
4840189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
4841189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4842189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
4843189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
4844189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
4845189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
4846189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
484714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
484814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
484914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
485014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
485114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
485214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
485314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
485414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
485514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
485653642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
485753642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
4858189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
4859189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
4860189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4861189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
4862189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
486314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
4864189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
4865189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
4866189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
4867fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
4868fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
4869fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
4870fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
4871fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
4872fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
4873fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
4874fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
487500c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
4876fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
487793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
487876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
487976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
488076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
488176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
488276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
488393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
488493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
488593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
48867260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
48877260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
48887260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
4889aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
489076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
4891aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
4892aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
489393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
489476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
489593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
489693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
489776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
489876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
4899aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
49007260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
49017260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
49027260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
490393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
490493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
490593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
490676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
490776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
490876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
490976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
491076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
491176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
491276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
49135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
49145402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // so only issue a diagnostic for thumb1. The instructions will be
49155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  // switched to the t2 encodings in processInstruction() if necessary.
49166dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
4917aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
49185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
49195402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
4920aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
4921aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
49226dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
49236dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
49246dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
4925aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
49265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
49275402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach        !isThumbTwo())
4928aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
4929aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
49306dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
49316dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
49321e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
49331e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
49348213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
49351e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
49361e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
49371e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
49381e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
4939189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
4940189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
4941189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
4942189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
4943189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
494484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVSTLNOpcode(unsigned Opc) {
494584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  switch(Opc) {
494684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  default: assert(0 && "unexpected opcode!");
494784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:   return ARM::VST1LNd8_UPD;
494884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_P8:  return ARM::VST1LNd8_UPD;
494984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I8:  return ARM::VST1LNd8_UPD;
495084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S8:  return ARM::VST1LNd8_UPD;
495184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U8:  return ARM::VST1LNd8_UPD;
495284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:  return ARM::VST1LNd16_UPD;
495384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_P16: return ARM::VST1LNd16_UPD;
495484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I16: return ARM::VST1LNd16_UPD;
495584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S16: return ARM::VST1LNd16_UPD;
495684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U16: return ARM::VST1LNd16_UPD;
495784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32:  return ARM::VST1LNd32_UPD;
495884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_F:   return ARM::VST1LNd32_UPD;
495984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_F32: return ARM::VST1LNd32_UPD;
496084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I32: return ARM::VST1LNd32_UPD;
496184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S32: return ARM::VST1LNd32_UPD;
496284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U32: return ARM::VST1LNd32_UPD;
496384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:   return ARM::VST1LNd8_UPD;
496484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_P8:  return ARM::VST1LNd8_UPD;
496584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I8:  return ARM::VST1LNd8_UPD;
496684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S8:  return ARM::VST1LNd8_UPD;
496784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U8:  return ARM::VST1LNd8_UPD;
496884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16:  return ARM::VST1LNd16_UPD;
496984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_P16: return ARM::VST1LNd16_UPD;
497084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I16: return ARM::VST1LNd16_UPD;
497184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S16: return ARM::VST1LNd16_UPD;
497284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U16: return ARM::VST1LNd16_UPD;
497384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32:  return ARM::VST1LNd32_UPD;
497484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_F:   return ARM::VST1LNd32_UPD;
497584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_F32: return ARM::VST1LNd32_UPD;
497684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I32: return ARM::VST1LNd32_UPD;
497784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S32: return ARM::VST1LNd32_UPD;
497884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U32: return ARM::VST1LNd32_UPD;
497984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_8:   return ARM::VST1LNd8;
498084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_P8:  return ARM::VST1LNd8;
498184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_I8:  return ARM::VST1LNd8;
498284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_S8:  return ARM::VST1LNd8;
498384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U8:  return ARM::VST1LNd8;
498484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_16:  return ARM::VST1LNd16;
498584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_P16: return ARM::VST1LNd16;
498684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_I16: return ARM::VST1LNd16;
498784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_S16: return ARM::VST1LNd16;
498884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U16: return ARM::VST1LNd16;
498984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_32:  return ARM::VST1LNd32;
499084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_F:   return ARM::VST1LNd32;
499184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_F32: return ARM::VST1LNd32;
499284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_I32: return ARM::VST1LNd32;
499384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_S32: return ARM::VST1LNd32;
499484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U32: return ARM::VST1LNd32;
499584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
499684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach}
499784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach
499884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbachstatic unsigned getRealVLDLNOpcode(unsigned Opc) {
49997636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  switch(Opc) {
50007636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  default: assert(0 && "unexpected opcode!");
5001872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:   return ARM::VLD1LNd8_UPD;
5002872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_P8:  return ARM::VLD1LNd8_UPD;
5003872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I8:  return ARM::VLD1LNd8_UPD;
5004872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S8:  return ARM::VLD1LNd8_UPD;
5005872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U8:  return ARM::VLD1LNd8_UPD;
5006872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:  return ARM::VLD1LNd16_UPD;
5007872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_P16: return ARM::VLD1LNd16_UPD;
5008872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I16: return ARM::VLD1LNd16_UPD;
5009872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S16: return ARM::VLD1LNd16_UPD;
5010872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U16: return ARM::VLD1LNd16_UPD;
5011872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32:  return ARM::VLD1LNd32_UPD;
5012872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_F:   return ARM::VLD1LNd32_UPD;
5013872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_F32: return ARM::VLD1LNd32_UPD;
5014872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I32: return ARM::VLD1LNd32_UPD;
5015872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S32: return ARM::VLD1LNd32_UPD;
5016872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U32: return ARM::VLD1LNd32_UPD;
5017872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:   return ARM::VLD1LNd8_UPD;
5018872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_P8:  return ARM::VLD1LNd8_UPD;
5019872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_I8:  return ARM::VLD1LNd8_UPD;
5020872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_S8:  return ARM::VLD1LNd8_UPD;
5021872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_U8:  return ARM::VLD1LNd8_UPD;
5022872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:  return ARM::VLD1LNd16_UPD;
5023872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_P16: return ARM::VLD1LNd16_UPD;
5024872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_I16: return ARM::VLD1LNd16_UPD;
5025872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_S16: return ARM::VLD1LNd16_UPD;
5026872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_U16: return ARM::VLD1LNd16_UPD;
5027872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32:  return ARM::VLD1LNd32_UPD;
5028872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_F:   return ARM::VLD1LNd32_UPD;
5029872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_F32: return ARM::VLD1LNd32_UPD;
5030872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_I32: return ARM::VLD1LNd32_UPD;
5031872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_S32: return ARM::VLD1LNd32_UPD;
5032872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_U32: return ARM::VLD1LNd32_UPD;
5033dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_8:   return ARM::VLD1LNd8;
5034dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_P8:  return ARM::VLD1LNd8;
5035dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_I8:  return ARM::VLD1LNd8;
5036dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_S8:  return ARM::VLD1LNd8;
5037dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_U8:  return ARM::VLD1LNd8;
5038872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdAsm_16:  return ARM::VLD1LNd16;
5039872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdAsm_P16: return ARM::VLD1LNd16;
5040872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdAsm_I16: return ARM::VLD1LNd16;
5041872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdAsm_S16: return ARM::VLD1LNd16;
5042872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdAsm_U16: return ARM::VLD1LNd16;
5043dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_32:  return ARM::VLD1LNd32;
5044dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_F:   return ARM::VLD1LNd32;
5045dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_F32: return ARM::VLD1LNd32;
5046dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_I32: return ARM::VLD1LNd32;
5047dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_S32: return ARM::VLD1LNd32;
5048dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_U32: return ARM::VLD1LNd32;
50497636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
50507636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach}
50517636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach
505283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbachbool ARMAsmParser::
5053f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
5054f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
5055f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
505684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  // Handle NEON VST1 complex aliases.
505784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_8:
505884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_P8:
505984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I8:
506084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S8:
506184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U8:
506284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_16:
506384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_P16:
506484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I16:
506584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S16:
506684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U16:
506784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_32:
506884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_F:
506984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_F32:
507084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_I32:
507184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_S32:
507284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_register_Asm_U32: {
507384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
507484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
507584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
507684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
507784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
507884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
507984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
508084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
508184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
508284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
508384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
508484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
508584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
508684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
508784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
508884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_8:
508984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_P8:
509084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I8:
509184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S8:
509284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U8:
509384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_16:
509484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_P16:
509584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I16:
509684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S16:
509784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U16:
509884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_32:
509984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_F:
510084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_F32:
510184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_I32:
510284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_S32:
510384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdWB_fixed_Asm_U32: {
510484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
510584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
510684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
510784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
510884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
510984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
511084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
511184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
511284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
511384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
511484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
511584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
511684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
511784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
511884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
511984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_8:
512084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_P8:
512184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_I8:
512284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_S8:
512384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U8:
512484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_16:
512584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_P16:
512684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_I16:
512784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_S16:
512884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U16:
512984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_32:
513084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_F:
513184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_F32:
513284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_I32:
513384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_S32:
513484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  case ARM::VST1LNdAsm_U32: {
513584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    MCInst TmpInst;
513684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
513784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    // right place.
513884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
513984defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
514084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
514184defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
514284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
514384defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
514484defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
514584defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    Inst = TmpInst;
514684defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    return true;
514784defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach  }
51487636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  // Handle NEON VLD1 complex aliases.
5149872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_8:
5150872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_P8:
5151872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_I8:
5152872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_S8:
5153872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_U8:
5154872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_16:
5155872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_P16:
5156872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_I16:
5157872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_S16:
5158872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_U16:
5159872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_32:
5160872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_F:
5161872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_F32:
5162872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_I32:
5163872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_S32:
5164872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_register_Asm_U32: {
5165872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5166872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5167872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
516884defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
5169872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5170872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5171872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5172872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5173872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rm
5174872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5175872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5176872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // CondCode
5177872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(6));
5178872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5179872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5180872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
5181872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_8:
5182872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_P8:
5183872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I8:
5184872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S8:
5185872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U8:
5186872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_16:
5187872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_P16:
5188872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I16:
5189872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S16:
5190872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U16:
5191872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_32:
5192872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_F:
5193872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_F32:
5194872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_I32:
5195872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_S32:
5196872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  case ARM::VLD1LNdWB_fixed_Asm_U32: {
5197872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    MCInst TmpInst;
5198872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // Shuffle the operands around so the lane index operand is in the
5199872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    // right place.
520084defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
5201872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
5202872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
5203872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
5204872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
5205872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
5206872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
5207872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
5208872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
5209872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
5210872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    Inst = TmpInst;
5211872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach    return true;
5212872eedbb3a46618e333db42ee9c41fda34eb1e9bJim Grosbach  }
5213dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_8:
5214dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_P8:
5215dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_I8:
5216dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_S8:
5217dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_U8:
5218dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_16:
5219dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_P16:
5220dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_I16:
5221dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_S16:
5222dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_U16:
5223dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_32:
5224dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_F:
5225dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_F32:
5226dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_I32:
5227dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_S32:
5228dad2f8e7fb2df5fb080a38fa4c33a01f19729f15Jim Grosbach  case ARM::VLD1LNdAsm_U32: {
52297636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    MCInst TmpInst;
52307636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // Shuffle the operands around so the lane index operand is in the
52317636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    // right place.
523284defb51ca183d136e08e87d95e2c907654405f9Jim Grosbach    TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
52337636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Vd
52347636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rn
52357636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // alignment
52367636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
52377636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // lane
52387636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // CondCode
52397636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5));
52407636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    Inst = TmpInst;
52417636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach    return true;
52427636bf6530fd83bf7356ae3894246a4e558741a4Jim Grosbach  }
524371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  // Handle the MOV complex aliases.
524423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::ASRr:
524523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSRr:
524623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::LSLr:
524723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  case ARM::RORr: {
524823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
524923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    switch(Inst.getOpcode()) {
525023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
525123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
525223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
525323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
525423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    case ARM::RORr: ShiftTy = ARM_AM::ror; break;
525523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    }
525623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
525723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
525823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    MCInst TmpInst;
525923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.setOpcode(ARM::MOVsr);
526023f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
526123f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
526223f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // Rm
526323f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
526423f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
526523f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
526623f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
526723f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    Inst = TmpInst;
526823f220705a74685edd743e84861a3e0d6d109828Jim Grosbach    return true;
526923f220705a74685edd743e84861a3e0d6d109828Jim Grosbach  }
5270ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::ASRi:
5271ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSRi:
5272ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::LSLi:
5273ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach  case ARM::RORi: {
5274ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    ARM_AM::ShiftOpc ShiftTy;
5275ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    switch(Inst.getOpcode()) {
5276ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    default: llvm_unreachable("unexpected opcode!");
5277ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
5278ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
5279ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
5280ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    case ARM::RORi: ShiftTy = ARM_AM::ror; break;
5281ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    }
5282ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    // A shift by zero is a plain MOVr, not a MOVsi.
528348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Amt = Inst.getOperand(2).getImm();
5284ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
5285ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
528671810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    MCInst TmpInst;
5287ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    TmpInst.setOpcode(Opc);
528871810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
528971810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
5290ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach    if (Opc == ARM::MOVsi)
5291ee10ff89a2934636570cb17b756bf31b2a38aab5Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
529271810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3)); // CondCode
529371810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
529471810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    TmpInst.addOperand(Inst.getOperand(5)); // cc_out
529571810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach    Inst = TmpInst;
529683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
529771810ab7c0ecd6927dde1eee0c73169642f3764dJim Grosbach  }
529848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  case ARM::RRXi: {
529948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
530048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    MCInst TmpInst;
530148b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.setOpcode(ARM::MOVsi);
530248b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rd
530348b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
530448b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
530548b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
530648b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
530748b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // cc_out
530848b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    Inst = TmpInst;
530948b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach    return true;
531048b368bcd5fd6d1857de137230ac019b8530f1cdJim Grosbach  }
53110352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2LDMIA_UPD: {
53120352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a load of a single register, then we should use
53130352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
53140352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
53150352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
53160352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
53170352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2LDR_POST);
53180352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
53190352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
53200352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
53210352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(4));
53220352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
53230352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
53240352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
53250352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
53260352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
53270352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  case ARM::t2STMDB_UPD: {
53280352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // If this is a store of a single register, then we should use
53290352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
53300352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    if (Inst.getNumOperands() != 5)
53310352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach      return false;
53320352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    MCInst TmpInst;
53330352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.setOpcode(ARM::t2STR_PRE);
53340352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
53350352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(4)); // Rt
53360352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(1)); // Rn
53370352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(MCOperand::CreateImm(-4));
53380352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(2)); // CondCode
53390352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
53400352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    Inst = TmpInst;
53410352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach    return true;
53420352b4679e9289ded6b2d73a76a017e0d97fe70dJim Grosbach  }
5343f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
5344f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
5345f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
5346f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
5347f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
5348f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
5349f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
5350f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
5351f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
5352f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
5353f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
5354f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
5355f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
5356f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5357f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
535883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
5359f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
5360f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
5361f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
5362f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
5363f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
5364f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
5365f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
5366f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
5367f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
5368f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
5369f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
5370f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
5371f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
5372f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
5373f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5374f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
5375f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
5376f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
5377da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2ADDri12:
5378da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2ADDri) and the generic "add"
5379da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "addw"), encoding T3 is preferred.
5380da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "add" ||
5381da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
5382da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
5383da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2ADDri);
5384da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
5385da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
5386da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach  case ARM::t2SUBri12:
5387da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // If the immediate fits for encoding T3 (t2SUBri) and the generic "sub"
5388da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    // mnemonic was used (not "subw"), encoding T3 is preferred.
5389da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() != "sub" ||
5390da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach        ARM_AM::getT2SOImmVal(Inst.getOperand(2).getImm()) == -1)
5391da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach      break;
5392da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.setOpcode(ARM::t2SUBri);
5393da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0)); // cc_out
5394da84786bee8304588a4325b15e297be1995a5d41Jim Grosbach    break;
539589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
53960f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
53970f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
53980f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
53990f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
540083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
540189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
540283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
540383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
540489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
5405f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
5406f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
5407f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
5408f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
5409f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
541083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6) {
5411f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
541283ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
541383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
5414f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
5415927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  case ARM::t2ADDrr: {
5416927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // If the destination and first source operand are the same, and
5417927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // there's no setting of the flags, use encoding T2 instead of T3.
5418927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // Note that this is only for ADD, not SUB. This mirrors the system
5419927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    // 'as' behaviour. Make sure the wide encoding wasn't explicit.
5420927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    if (Inst.getOperand(0).getReg() != Inst.getOperand(1).getReg() ||
5421927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach        Inst.getOperand(5).getReg() != 0 ||
5422713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach        (static_cast<ARMOperand*>(Operands[3])->isToken() &&
5423713c70238c6d150d2cd458b07ab35932fafe508eJim Grosbach         static_cast<ARMOperand*>(Operands[3])->getToken() == ".w"))
5424927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach      break;
5425927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    MCInst TmpInst;
5426927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.setOpcode(ARM::tADDhirr);
5427927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
5428927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(0));
5429927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(2));
5430927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(3));
5431927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    TmpInst.addOperand(Inst.getOperand(4));
5432927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    Inst = TmpInst;
5433927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach    return true;
5434927b9df4c678371d3fb1308be90e76ed44af72f8Jim Grosbach  }
543551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
543651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
543783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) {
543851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
543983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
544083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
544151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
544251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
544351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
544483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()){
544551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
544683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
544783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
544851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
5449c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
5450a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
545183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) {
5452c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
545383ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
545483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
5455c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
5456395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
5457395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
545883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL) {
5459395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
546083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
546183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    }
54623ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
546376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
546476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
546576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
546676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
546776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
546876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
546976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
547076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
547176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
547276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
547376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
547476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
547576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
547676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
547776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
547876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
547976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
548076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
548176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
548276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
548376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
548483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
548576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
548676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
548776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
54888213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
54898213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
54908213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
54918213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
54928213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
54938213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
54948213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
54958213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
54968213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
54978213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
549883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
54998213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
55008213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
55018213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
55025402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPOP: {
55035402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
55045402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // If the register list contains any high registers, we need to use
55055402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
55065402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // should have generated an error in validateInstruction().
55075402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
550883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
55095402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
55105402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2LDMIA_UPD);
55115402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
55125402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
55135402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
551483ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
55155402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
55165402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  case ARM::tPUSH: {
55175402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    bool listContainsBase;
55185402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
551983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return false;
55205402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    assert (isThumbTwo());
55215402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.setOpcode(ARM::t2STMDB_UPD);
55225402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    // Add the base register and writeback operands.
55235402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
55245402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach    Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
552583ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    return true;
55265402637ff283d7397513d5c1699cdf2274c47313Jim Grosbach  }
55271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
55281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
55291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
55301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
55311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
5532c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
5533c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
5534c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
55351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
55361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
55371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
55381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
55391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
55401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
55411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
55421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
55431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
55441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
55451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
554683ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
55471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
55481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
55491ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
55501ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
55511ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
55521ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
55531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
55541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
55551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
55561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
55571ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
55581ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
55591ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
55601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
55611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
55621ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
55631ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
55641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
55651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
55661ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
556783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
55681ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
55691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
55701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
5571326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
557250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
557350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
557450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
5575326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
5576326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
5577326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
5578326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
5579326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
5580326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
5581326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
558250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
558350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
558450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
558550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
558650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
558750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
558850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
558950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
5590326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
5591326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
5592326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
5593326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
5594326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
5595326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
5596326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
5597326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
559883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      return true;
5599326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
5600326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
5601326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
560289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
560389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
560489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
560589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
560689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
560789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
560889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
560989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
561089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
5611f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
5612f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
561389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
561489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
561589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
561689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
561789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
561889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
561989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
5620f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
5621f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
5622f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
5623f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
5624f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
5625f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
5626f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
5627f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
562889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
562989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
5630f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
563183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach  return false;
5632f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
5633f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
563447a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
563547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
563647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
5637194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
56381a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer  const MCInstrDesc &MCID = getInstDesc(Opc);
563947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
564047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
564147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
564247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
564347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
564447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
564547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
564647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
564747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
564847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
564947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
565047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
565147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
565247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
565347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
565447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
5655f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
5656f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
565747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
5658f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
5659f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
5660f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
566147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
5662194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
5663194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
5664194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
5665194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
5666194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
5667194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
5668194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
56694ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
5670194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
5671194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
5672194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
567347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
567447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
567547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
5676fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
5677fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
5678fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
5679fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
5680fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
5681fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
568219cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
5683193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
5684193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
568519cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
5686e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
5687189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
5688189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
5689a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
5690a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
5691a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
5692a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
5693189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
5694a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
5695189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
5696f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
569783ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // encoding is selected. Loop on it while changes happen so the
569883ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // individual transformations can chain off each other. E.g.,
569983ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    // tPOP(r8)->t2LDMIA_UPD(sp,r8)->t2STR_POST(sp,r8)
570083ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach    while (processInstruction(Inst, Operands))
570183ec87755ed4d07f6650d6727fb762052bd0041cJim Grosbach      ;
5702f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
5703a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
5704a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
5705a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
5706a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
5707a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
5708fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
5709fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
5710e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
5711e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
5712e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
5713e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
5714e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
5715e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
5716e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
5717e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
571816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
5719e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
5720e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
5721e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
572216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
5723e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
5724e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
5725e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
572647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
5727b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
572888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
572988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
5730f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
5731f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
573247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
573347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
5734194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
5735194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
5736194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
5737194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
5738fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
573916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
5740c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
5741146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
5742fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
5743fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
57441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
5745ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
5746ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
5747ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
57481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
5749515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
57501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
57519a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  else if (IDVal == ".arm")
57529a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return parseDirectiveARM(DirectiveID.getLoc());
5753515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
57541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
5755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
57561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
5757515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
57581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
5759ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
5760ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5761ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
57621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
5763ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
57641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
5765ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5766ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
5767ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
5768ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
5769ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
5770ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5771aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
5772ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5773ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
5774ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
577516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
5776ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
5777ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
5778ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
5779b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
5780ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
5781ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
5782ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
5783b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
5784ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
5785ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
5786ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
57871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
5788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
57891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
5790515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
5791515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
5792b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
5793515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
57949a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (!isThumb())
57959a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
57969a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
57979a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  return false;
57989a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach}
57999a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
58009a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach/// parseDirectiveARM
58019a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach///  ::= .arm
58029a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbachbool ARMAsmParser::parseDirectiveARM(SMLoc L) {
58039a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (getLexer().isNot(AsmToken::EndOfStatement))
58049a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    return Error(L, "unexpected token in directive");
58059a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  Parser.Lex();
58069a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach
58079a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  if (isThumb())
58089a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach    SwitchMode();
58099a70df99ca674b288d50dbf454779ed75d6e48ddJim Grosbach  getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
5810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
5811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
5812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
58131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
5814515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
58151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
58166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
58176469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
58186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
58196469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
58206469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
58216469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
58226469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
58236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
58246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
58256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
5826d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Tok.getIdentifier();
58276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
58286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
58296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
5830d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement))
5831515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
5832b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
5833515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
58346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
58356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
5836d475f8612b1c7959dbf50242c8fa9d4aea1ee1a9Jim Grosbach    Name = Parser.getTok().getIdentifier();
58376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
58386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
5839642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
5840642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
5841642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
5842515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
5843515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
5844515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
58451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
5846515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
58471355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
584818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
5849515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
5850515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
585138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
585258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
5853b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
585458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
58559e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
5856515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
5857515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
5858515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
5859515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
586018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
5861b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
5862515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
5863515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
5864515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
5865515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
5866515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
5867515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
58681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
5869515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
58701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
587118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
5872515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
5873515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
587418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
587558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
5876b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
587758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
5878b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
5879515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
5880515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
5881515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
5882515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
588318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
5884b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
5885515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
588632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
588798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
5888ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
588998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
589032869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
589198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
5892ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
589398447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
5894eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
58952a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
5896515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
5897515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
5898515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
589990b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
590090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
59019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
5902ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
590394b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
590494b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
590590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
5906ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
59073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
59080692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
59090692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
59103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
5911