ARMAsmParser.cpp revision b6310316dbaf8716003531d7ed245f77f1a76a11
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"
330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
34345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
35c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4394b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
67a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
75f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
77ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
850d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
941355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
97515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
9989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
10089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
102fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
10316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
104ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
105ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
106ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
108ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
109ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
110ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
11147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
11247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
11347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
114194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
115194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
116194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
117acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool hasV7Ops() const {
118acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::HasV7Ops;
119acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
12032869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
121ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
122ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
12332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
124acad68da50581de905a994ed3c6b9c197bcea687James Molloy  bool isMClass() const {
125acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return STI.getFeatureBits() & ARM::FeatureMClass;
126acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
127ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1310692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1320692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
13689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
13743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
138f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
1419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  OperandMatchResultTy parseCoprocOptionOperand(
1429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
14343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1488bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
157c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
158580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
160293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
162251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1639d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
164862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
165ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
166ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
167a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
168a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
169a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
170a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
171eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
172eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
173ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
174ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
176ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1779ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1789ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
179548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
180548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
182ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1837b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1847b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
1942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
19514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
19614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
197623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
198623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
19988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
20088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
201189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
202189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
203189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
204f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  void processInstruction(MCInst &Inst,
205f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
206d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
207d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
208189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
209ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
21047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
211194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
212f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
213194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
214194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
21547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
21647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
217ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
21894b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
219ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
22032869205052430f45d598fba25ab878d8b29da2dEvan Cheng
221ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
222ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
224f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
225f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
226ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
227ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
231189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
23447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
23547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
239ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
24016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
24116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2423a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2433a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
244a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
245a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
246146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
247762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
24821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
24921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
25021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
25121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
25221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
2539b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    k_CoprocOption,
25421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
25521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_FPImmediate,
25621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
25721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
25821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
261460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
266862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    k_VectorList,
26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
26821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
26921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
27021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
27121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
27221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
275762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
27624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
2828462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2838462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
285fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
286fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
287fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
2889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      unsigned Val;
2899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    } CoprocOption;
2909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    struct {
29289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
29389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
29489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
29589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
29689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
29789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
29889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
29989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
302a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
311a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
316862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // A vector register list is a sequential list of 1 to 4 registers.
317862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    struct {
318862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned RegNum;
319862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      unsigned Count;
320862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    } VectorList;
321862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
3228155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
323460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
324460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
325460a90540b045c102012da2492999557e6840526Jim Grosbach
326460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
327cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
328cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
32916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3309d39036f62674606565217a10db28171b9594bc7Jim Grosbach    struct {
3319d39036f62674606565217a10db28171b9594bc7Jim Grosbach      unsigned Val;       // encoded 8-bit representation
3329d39036f62674606565217a10db28171b9594bc7Jim Grosbach    } FPImm;
3339d39036f62674606565217a10db28171b9594bc7Jim Grosbach
3346a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
335a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
336a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
34257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned ShiftImm;        // shift for OffsetReg.
34357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      unsigned Alignment;       // 0 = no alignment specified
34457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                // n = alignment in bytes (8, 16, or 32)
3457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
346e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    } Memory;
3470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
350f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
351f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
352f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
356580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
357e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
358580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
359e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
360e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
361e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
362e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
363e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
364af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
36592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
36692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
36792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
36892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
369af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
373293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
374293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
375293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
376293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
37816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
379146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
380146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
382762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
383762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
384762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
385762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
38621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
3878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
3888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
38921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
39089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
39189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
39221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
3938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
394762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
39521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
39621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
397762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
398762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
39921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
40121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
40224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
4038d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
404862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    case k_VectorList:
405862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      VectorList = o.VectorList;
406862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      break;
40721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
40821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
409fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
4119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    case k_CoprocOption:
4129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      CoprocOption = o.CoprocOption;
4139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach      break;
41421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
415762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
416762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
41721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_FPImmediate:
4189d39036f62674606565217a10db28171b9594bc7Jim Grosbach      FPImm = o.FPImm;
4199d39036f62674606565217a10db28171b9594bc7Jim Grosbach      break;
42021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
421706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
422706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
42321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
424e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Memory = o.Memory;
425762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
42621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
42921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
430584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
431584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
43221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
433a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
43521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
43821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
439af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
440e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
44121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
442af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
44392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
44421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
44721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
448293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
449293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
450460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
451460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
452460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
453762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
454762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
45516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
456762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
457762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
459762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
460a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
46221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
466fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
46721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
468fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
469fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
471a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
47221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
473a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
476a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
47721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4787729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
480a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4815fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
48221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
48321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
48424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
4858d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
4868d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
487cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
48821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Immediate && "Invalid access!");
489cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
490cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
491cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
4929d39036f62674606565217a10db28171b9594bc7Jim Grosbach  unsigned getFPImm() const {
49321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_FPImmediate && "Invalid access!");
4949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return FPImm.Val;
4959d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
4969d39036f62674606565217a10db28171b9594bc7Jim Grosbach
497460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
498460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
499460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
500460a90540b045c102012da2492999557e6840526Jim Grosbach  }
501460a90540b045c102012da2492999557e6840526Jim Grosbach
502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
505706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
507a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
50821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
509a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
510a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
511a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
51321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
515584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
516584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
51721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
51821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
5199b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  bool isCoprocOption() const { return Kind == k_CoprocOption; }
52021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
52121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
52221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
52321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
52421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
52521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isFPImm() const { return Kind == k_FPImmediate; }
526a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
52721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
528a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
529a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
530a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
531a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
532a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
533a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
53472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
53672f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
53772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
53872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
53972f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
54072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
54172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
54272f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
54472f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
54572f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
54672f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
54772f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
54872f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
54972f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5506b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
5536b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5546b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
55883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
56083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
56183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
56283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
56383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
56483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
56583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
56683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
56883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
56983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
57183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
57283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
57383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
5747c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
57521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5767c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
5777c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5787c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
5797c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
5807c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
5817c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
582f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
58321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
584f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
585f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
586f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
587f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
588f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
589f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
5904a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
59121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5924a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
5934a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5944a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
5954a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
5964a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
5974a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
598fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
59921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
600fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
601fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
602fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
603fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
604fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
605fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
606ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
60721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
608ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
609ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
610ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
611ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
612ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
613ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
614ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
615ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
616ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
61721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
618ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
619ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
620ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
621ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
622ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
623ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
62470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
62521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
62670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
62770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
62870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
62970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
63070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
63170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
632f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
63321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
638f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
639f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
640f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
64121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
642f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
643f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
644f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
645f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
6486bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
64921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
6506bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
6516bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6526bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
6536bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
6546bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
6556bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
6566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
65721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
6586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
6596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6606b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
6616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
6626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
6636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
664c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
66521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
666c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
667c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
668c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
669c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
670c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
671c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
67221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
67321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
67421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
67521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
67621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
67721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
67821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
67921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
68021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
68121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
68221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
68321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
68421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
685f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
68621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
687f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
68857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isMemNoOffset(bool alignOK = false) const {
689f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
690ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
6917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
69257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return Memory.OffsetRegNum == 0 && Memory.OffsetImm == 0 &&
69357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     (alignOK || Memory.Alignment == 0);
69457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
69557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  bool isAlignedMemory() const {
69657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return isMemNoOffset(true);
697ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
6987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
69957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
7007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
701e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
7027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
703e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
704e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
7057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
7067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
707039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
70821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
709039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
710039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
711039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
712039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
713039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
714039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
715039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
7162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
71757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
7182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
719e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::no_shift) return false;
7202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
721e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return true;
7222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
723e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
724e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
7252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
7262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
7272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
72821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
7292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
73021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
7312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
7322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
7332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
7352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
736251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
737251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
7382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
7397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
74057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.Alignment != 0) return false;
7417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
742e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.OffsetRegNum) return false;
7437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
744e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
745e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
7460da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
7470da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson           Val == INT32_MIN;
7487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
7497f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
750e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
75157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
7527f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
7537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
7547f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
7557f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
756e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
75757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm != 1 ||
75857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0 )
7597f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
7607f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
7617f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
7627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
76357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.Alignment != 0)
764ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
765ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
766ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
767ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
76857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
76957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.Alignment != 0)
770ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
771ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
772e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType == ARM_AM::no_shift)
773ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
774e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (Memory.ShiftType != ARM_AM::lsl || Memory.ShiftImm > 3)
775ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
776ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
777ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
7787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
7797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
7807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
781e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || !Memory.OffsetRegNum || Memory.isNegative ||
78257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.ShiftType != ARM_AM::no_shift || Memory.Alignment != 0)
78387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
784e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    return isARMLowRegister(Memory.BaseRegNum) &&
785e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      (!Memory.OffsetRegNum || isARMLowRegister(Memory.OffsetRegNum));
78660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
78760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
788e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
78957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
79060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
79160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
792e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
793e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
794ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
795ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
79638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
797e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
79857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
79938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
80038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
801e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
802e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
80338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
80438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
80548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
806e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
80757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        !isARMLowRegister(Memory.BaseRegNum) || Memory.Alignment != 0)
80848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
80948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
811e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
81248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
81348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
814ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
81557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 ||
81657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach        Memory.BaseRegNum != ARM::SP || Memory.Alignment != 0)
817ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
818ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
819e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
820e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
821ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
822505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
823a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
82457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
825a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
826a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
827e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
828e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
829a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
830a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
831b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
83257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
833b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
834b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
835e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
836e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
837b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
838b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
8397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
84057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
841f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
8427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
843e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
844e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8454d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
846f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
847f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
84857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
849f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
850f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
851e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
852e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
853f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
854f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
855a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
85657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
857a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
858a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
859e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
860e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
861a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return Val > -256 && Val < 0;
862a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
863a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
864a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
865a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
866a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // and we reject it.
86721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
868a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return true;
869a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
87057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
871a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
872a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
873e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
874e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
875a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
876a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
8777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
87809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
87909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
88009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
88121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
88209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
88309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
88457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!isMemory() || Memory.OffsetRegNum != 0 || Memory.Alignment != 0)
885ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
8867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
887e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetImm) return true;
888e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm->getValue();
8890da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
8917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
89221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
8937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
8947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
895ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
8967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
89763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
898ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
8992bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  bool isPostIdxImm8s4() const {
9002bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Kind != k_Immediate)
9012bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      return false;
9022bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9032bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (!CE) return false;
9042bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int64_t Val = CE->getValue();
9052bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    return ((Val & 3) == 0 && Val >= -1020 && Val <= 1020) ||
9062bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      (Val == INT32_MIN);
9072bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
9087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
90921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
91021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
9113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9120e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // NEON operands.
913862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  bool isVecListOneD() const {
914862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Kind != k_VectorList) return false;
915862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return VectorList.Count == 1;
916862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
917862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
918280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  bool isVecListTwoD() const {
919280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    if (Kind != k_VectorList) return false;
920280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    return VectorList.Count == 2;
921280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
922280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
923cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  bool isVecListThreeD() const {
924cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    if (Kind != k_VectorList) return false;
925cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    return VectorList.Count == 3;
926cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
927cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
928b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  bool isVecListFourD() const {
929b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    if (Kind != k_VectorList) return false;
930b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    return VectorList.Count == 4;
931b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
932b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
933460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
934460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
935460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
936460a90540b045c102012da2492999557e6840526Jim Grosbach  }
937460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
938460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
939460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
940460a90540b045c102012da2492999557e6840526Jim Grosbach  }
941460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
942460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
943460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
944460a90540b045c102012da2492999557e6840526Jim Grosbach  }
945460a90540b045c102012da2492999557e6840526Jim Grosbach
9460e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  bool isNEONi8splat() const {
9470e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (Kind != k_Immediate)
9480e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach      return false;
9490e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9500e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Must be a constant.
9510e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    if (!CE) return false;
9520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    int64_t Value = CE->getValue();
9530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // i8 value splatted across 8 bytes. The immediate is just the 8 byte
9540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // value.
9550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return Value >= 0 && Value < 256;
9560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
957460a90540b045c102012da2492999557e6840526Jim Grosbach
958ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  bool isNEONi16splat() const {
959ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Kind != k_Immediate)
960ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      return false;
961ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
962ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // Must be a constant.
963ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (!CE) return false;
964ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    int64_t Value = CE->getValue();
965ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // i16 value in the range [0,255] or [0x0100, 0xff00]
966ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
967ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
968ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
9696248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32splat() const {
9706248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Kind != k_Immediate)
9716248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      return false;
9726248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9736248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
9746248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
9756248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
9766248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
9776248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
9786248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
9796248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
9806248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000);
9816248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
9826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
9836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  bool isNEONi32vmov() const {
9846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Kind != k_Immediate)
9856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      return false;
9866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // Must be a constant.
9886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (!CE) return false;
9896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    int64_t Value = CE->getValue();
9906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
9916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
9926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    return (Value >= 0 && Value < 256) ||
9936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x0100 && Value <= 0xff00) ||
9946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x010000 && Value <= 0xff0000) ||
9956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01000000 && Value <= 0xff000000) ||
9966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
9976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
9986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
9996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1000f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  bool isNEONi64splat() const {
1001f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (Kind != k_Immediate)
1002f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      return false;
1003f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1004f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // Must be a constant.
1005f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    if (!CE) return false;
1006f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1007f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // i64 value with each byte being either 0 or 0xff.
1008f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i)
1009f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff) return false;
1010f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    return true;
1011f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1012f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
10133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
101414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
101514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
101614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
101714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
10183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
10193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
10203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
10213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
10223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1024345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
10258462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
102604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
102704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
10288462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
10298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1030fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
1031fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1032fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
10359b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
10369b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
10379b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
10389b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
10399b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
10409b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  void addCoprocOptionOperands(MCInst &Inst, unsigned N) const {
10419b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    assert(N == 1 && "Invalid number of operands!");
10429b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CoprocOption.Val));
10439b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
10449b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
104589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
104689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
104789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
104889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
104989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
105089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
105189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
105289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
105389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
105489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
1055d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
1056d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1057d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
1058d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1059d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
1060a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
1061a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
1062a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
1063a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1064a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1065af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
1066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1067af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
1068af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
1069af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
1070e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
1071af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
1072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1073e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1074af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
1075152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
1076af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
1077af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
107892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
1079af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
108092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
108192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1082580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
10830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
1084580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
1085580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
10860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
10870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
108887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
10897729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
10905fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
10915fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
10927729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
10937729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
109487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
109587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
10960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
10970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
10980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
10990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
11000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
11010f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
11020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
11030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
11047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
11057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
11077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
11087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
11097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1110293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
1111293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1112293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
1113293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
1114293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
1115293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
1116293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
1117293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
1118293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
1119293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1120293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
11213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
11226b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11236b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
11246b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
11256b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
11269d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
11279d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11289d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getFPImm()));
11299d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
11309d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1131a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1132a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1133a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1134a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1135a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1136a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1137a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1138a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
113972f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
114072f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
114172f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
114272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
114372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
114472f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
114572f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
114672f39f8436848885176943b0ba985a7171145423Jim Grosbach
114772f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
114872f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
114972f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
115072f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
115172f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
115272f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
115372f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
115472f39f8436848885176943b0ba985a7171145423Jim Grosbach
11556b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
11566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
11586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
11596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
116083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
116183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
116283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
116383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
116483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
116583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
11667c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11677c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
11687c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
11697c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
11707c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
117183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
117283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
117383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
117483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
1175f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1176f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1177f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1178f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1179f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1180f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1181f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1182f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
11834a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
11844a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
11854a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
11864a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
11874a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11884a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
11894a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
11904a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
1191fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1192fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1193fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
1194fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
1195fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
1196ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
1197ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1198ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
1199ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
1200ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach
1201ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
1202ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1203ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    addExpr(Inst, getImm());
120470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
120570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach
120670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
120770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
120870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
120970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
121070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
121170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
121270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1213ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1214ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1215f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
1216f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1217f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
1218f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1219f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1220f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1221f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1222f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1223f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1224f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1225f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1226f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1227f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1228f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
12296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
12306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
12316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
12326bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
12336bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
12346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
12353483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
12363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
12373483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
123816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1239c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
1240c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1241c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
1242c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1243c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1244706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1245706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1246706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1247706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1248706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
12497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
12507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1251e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1252505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1253505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
125457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  void addAlignedMemoryOperands(MCInst &Inst, unsigned N) const {
125557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
125657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
125757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.Alignment));
125857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
125957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
12607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
12617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1262e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1263e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
12647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
12657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
12667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
12677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
12687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
12707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
1272e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1273e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                              Memory.ShiftImm, Memory.ShiftType);
1274ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
1275e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1276e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
12777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1278ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1279ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1280039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1281039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1282039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1283039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1284039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1285039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1286039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1287039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1288039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1289039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1290039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1291039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1292039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1293039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
12942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
12952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1296e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1297e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    if (!Memory.OffsetRegNum) {
12982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
12992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
13002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
13012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
13022fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
13032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
13042fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
13052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
1306e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach      Val = ARM_AM::getAM3Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
13072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
1308e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1309e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
13102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
13112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
13122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
13132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
13142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
131521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
13162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
13172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
13182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
13192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1320251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
13212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
13222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
13232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
13242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
13252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
13262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
13272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
13282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
13292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1330251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
13312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
13322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
13332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
13342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
13357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
13367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
13377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1338e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
13397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
13407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
13417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
13427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
13437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
1344e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
13457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
13467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
13477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1348a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1349a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1350e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1351e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1352a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1353a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1354a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1355b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1356b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1357b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1358e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int32_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() / 4 : 0;
1359e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1360b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1361b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1362b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
13637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
13647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1365e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1366e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
13677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1368ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1369ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1370f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1371f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1372f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1373f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1374a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1375f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1376a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1377a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1378a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1379a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1380a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
138121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
1382a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1383a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1384a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1385a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1386a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1387a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1388e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1389e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1390a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1391a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1392a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
13937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
13947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
139509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
139621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
139709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
139809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
139909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
140009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
140109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
140209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1403e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? Memory.OffsetImm->getValue() : 0;
1404e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
14057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
140792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
14087f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
14097f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1410e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1411e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
14127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
14137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
14147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
14157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1416e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1417e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
14187f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
14197f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
14207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
14217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
1422e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    unsigned Val = ARM_AM::getAM2Opc(Memory.isNegative ? ARM_AM::sub : ARM_AM::add,
1423e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach                                     Memory.ShiftImm, Memory.ShiftType);
1424e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1425e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
14267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
14277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1428d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1429ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1430ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1431e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1432e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
1433e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Memory.ShiftImm));
1434ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1435ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
14367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
14377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1438e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1439e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.OffsetRegNum));
144014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
14413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
144260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
144360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1444e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1445e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
144660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
144748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
144848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
144938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
145038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1451e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 2) : 0;
1452e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
145338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
145438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
145538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
145648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
145748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1458e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue()) : 0;
1459e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
146048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
146160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
146260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1463ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1464ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1465e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    int64_t Val = Memory.OffsetImm ? (Memory.OffsetImm->getValue() / 4) : 0;
1466e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Memory.BaseRegNum));
1467ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1468ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1469ecd858968384be029574d845eb098d357049e02eJim Grosbach
14707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
14717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
14727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
14747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
14757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
147663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
14777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
14787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1479f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1480ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
14812bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  void addPostIdxImm8s4Operands(MCInst &Inst, unsigned N) const {
14822bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
14832bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
14842bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    assert(CE && "non-constant post-idx-imm8s4 operand!");
14852bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    int Imm = CE->getValue();
14862bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    bool isAdd = Imm >= 0;
14872bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    if (Imm == INT32_MIN) Imm = 0;
14882bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    // Immediate is scaled by 4.
14892bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Imm = ((Imm < 0 ? -Imm : Imm) / 4) | (int)isAdd << 8;
14902bd0118472de352745a2e038245fab4974f7c87eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
14912bd0118472de352745a2e038245fab4974f7c87eJim Grosbach  }
14922bd0118472de352745a2e038245fab4974f7c87eJim Grosbach
14937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
14947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
14957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1496f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1497f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1498f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1499f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1500f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1501f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1502f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1503f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1504f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1505f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1506f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1507f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1508ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1509ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1510584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1511584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1513584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1520862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  void addVecListOneDOperands(MCInst &Inst, unsigned N) const {
1521862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1522862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1523862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1524862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1525280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  void addVecListTwoDOperands(MCInst &Inst, unsigned N) const {
1526280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1527280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    // Only the first register actually goes on the instruction. The rest
1528280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    // are implied by the opcode.
1529280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1530280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach  }
1531280dfad48940a0a51726308dd3daa3b1b0d18705Jim Grosbach
1532cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  void addVecListThreeDOperands(MCInst &Inst, unsigned N) const {
1533cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1534cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    // Only the first register actually goes on the instruction. The rest
1535cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    // are implied by the opcode.
1536cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1537cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach  }
1538cdcfa280568d5d48ebeba2dcfc87915105e090d1Jim Grosbach
1539b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  void addVecListFourDOperands(MCInst &Inst, unsigned N) const {
1540b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1541b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    // Only the first register actually goes on the instruction. The rest
1542b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    // are implied by the opcode.
1543b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
1544b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach  }
1545b6310316dbaf8716003531d7ed245f77f1a76a11Jim Grosbach
1546460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1547460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1548460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1549460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1550460a90540b045c102012da2492999557e6840526Jim Grosbach
1551460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1552460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1553460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1554460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1555460a90540b045c102012da2492999557e6840526Jim Grosbach
1556460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1557460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1558460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1559460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1560460a90540b045c102012da2492999557e6840526Jim Grosbach
15610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  void addNEONi8splatOperands(MCInst &Inst, unsigned N) const {
15620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // The immediate encodes the type of constant as well as the value.
15640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    // Mask in that this is an i8 splat.
15650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() | 0xe00));
15670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  }
15680e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
1569ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  void addNEONi16splatOperands(MCInst &Inst, unsigned N) const {
1570ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1571ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    // The immediate encodes the type of constant as well as the value.
1572ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1573ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    unsigned Value = CE->getValue();
1574ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    if (Value >= 256)
1575ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value = (Value >> 8) | 0xa00;
1576ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    else
1577ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach      Value |= 0x800;
1578ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
1579ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach  }
1580ea46110f57b293844a314aec3b8092adf21ff63fJim Grosbach
15816248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
15826248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15836248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
15846248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15856248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
15866248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xff00)
15876248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | 0x200;
15886248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xff0000)
15896248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | 0x400;
15906248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
15916248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
15926248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
15936248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
15946248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
15956248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
15966248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
15976248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    // The immediate encodes the type of constant as well as the value.
15986248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
15996248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    unsigned Value = CE->getValue();
16006248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    if (Value >= 256 && Value <= 0xffff)
16016248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
16026248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffff && Value <= 0xffffff)
16036248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
16046248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    else if (Value > 0xffffff)
16056248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach      Value = (Value >> 24) | 0x600;
16066248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Value));
16076248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach  }
16086248a546f23e7ffa84c171dc364b922e28467275Jim Grosbach
1609f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  void addNEONi64splatOperands(MCInst &Inst, unsigned N) const {
1610f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1611f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    // The immediate encodes the type of constant as well as the value.
1612f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1613f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    uint64_t Value = CE->getValue();
1614f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    unsigned Imm = 0;
1615f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    for (unsigned i = 0; i < 8; ++i, Value >>= 8) {
1616f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach      Imm |= (Value & 1) << i;
1617f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    }
1618f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm | 0x1e00));
1619f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach  }
1620f2f5bc60f61acf0490d856ddd09e461bf93c5459Jim Grosbach
1621b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1622b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
162389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
162421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
162589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
162689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
162789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
162889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
162989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
163089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
16313a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
163221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1633345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1634345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1635345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
16363a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1637345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1638345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1639fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
164021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1641fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1642fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1643fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1644fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1645fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1646fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1647fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
164821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
1649fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1650fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1651fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1652fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1653fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1654fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
16559b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  static ARMOperand *CreateCoprocOption(unsigned Val, SMLoc S, SMLoc E) {
16569b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocOption);
16579b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->Cop.Val = Val;
16589b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->StartLoc = S;
16599b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Op->EndLoc = E;
16609b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return Op;
16619b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
16629b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
1663d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
166421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
1665d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1666d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1667d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1668d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1669d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1670d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
16713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
167221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
1673762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1674762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1675762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1676762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
16773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1678a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1679a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
168050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
168121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
1682762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1683762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1684762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
16853a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1688e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1689e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1690e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1691e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1692e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
169321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
1694af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1695af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1696af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1697af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1698e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1699e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1700e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1701e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1702e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
170392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
170492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
170592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
170692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
170721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
1708af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1709af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1710af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
171192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
171292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
171392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
171492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
171592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
17170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
171821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
1719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
17210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
17220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
17230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
17240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
17250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
17267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
172721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
17287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
17297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
17307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
17317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
17327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1734293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1735293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
173621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
1737293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1738293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1739293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1740293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1741293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1742293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1743293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
17447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
17455fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1746cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
174721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
17480f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1749d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
175021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
1751d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
1752275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
175321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
17540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
17550f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
17565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
17577729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
175824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1759cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1760cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1761cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
17628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
17638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
17648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
1765862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
1766862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach                                      SMLoc S, SMLoc E) {
1767862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorList);
1768862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.RegNum = RegNum;
1769862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->VectorList.Count = Count;
1770862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->StartLoc = S;
1771862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Op->EndLoc = E;
1772862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return Op;
1773862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
1774862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
1775460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1776460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
1777460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
1778460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
1779460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
1780460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
1781460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
1782460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1783460a90540b045c102012da2492999557e6840526Jim Grosbach
17843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
178521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
1786762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1787762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1788762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
17893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1790cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1791cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
17929d39036f62674606565217a10db28171b9594bc7Jim Grosbach  static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
179321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_FPImmediate);
17949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->FPImm.Val = Val;
17959d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->StartLoc = S;
17969d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->EndLoc = S;
17979d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return Op;
17989d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
17999d39036f62674606565217a10db28171b9594bc7Jim Grosbach
18007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
18017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
18027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
18037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
18040d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
180557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                               unsigned Alignment,
18067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
18073a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
180821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
1809e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.BaseRegNum = BaseRegNum;
1810e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetImm = OffsetImm;
1811e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.OffsetRegNum = OffsetRegNum;
1812e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftType = ShiftType;
1813e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.ShiftImm = ShiftImm;
181457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Op->Memory.Alignment = Alignment;
1815e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach    Op->Memory.isNegative = isNegative;
18167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
18177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
18187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
18197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
182016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1821f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1822f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
1823f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
18247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
182521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
18267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
1827f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
1828f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
1829f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
1830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
18323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1833a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1834706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1835706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
183621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
1837706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1838706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1839706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1840706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1841706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1842a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1843a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
184421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
1845a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1846a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1847a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1848a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1850584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1851584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
185221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
1853584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1854584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1855584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1856584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1857584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1858a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1859a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1860a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1861a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1862b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1863fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
186421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_FPImmediate:
18659d39036f62674606565217a10db28171b9594bc7Jim Grosbach    OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm())
18669d39036f62674606565217a10db28171b9594bc7Jim Grosbach       << ") >";
18679d39036f62674606565217a10db28171b9594bc7Jim Grosbach    break;
186821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
18696a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1870fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
187121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
1872d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1873d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
187421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
187589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)",
187689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)",
187789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(tee)", "(eee)" };
187889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
187989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
188089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
188189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
188221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
1883fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1884fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
188521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
1886fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1887fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
18889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  case k_CoprocOption:
18899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    OS << "<coprocessor option: " << CoprocOption.Val << ">";
18909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    break;
189121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
1892584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1893584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
189421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
1895fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1896fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
189721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
1898706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1899706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
190021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
19016ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
1902e53c87b302b3ae07c781405572170b0b6641b524Jim Grosbach       << " base:" << Memory.BaseRegNum;
19036ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1904fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
190521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
1906f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
1907f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
1908f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
1909f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
1910f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
1911f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
19127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
191321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
1914a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1915a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1918a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1919a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1920a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1921a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
192221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
192350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1924fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
192521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
1926580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1927580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
1928e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
192921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
193092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1931af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedReg.SrcReg
1932af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1933af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << RegShiftedReg.ShiftReg << ", "
1934af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1935e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
19360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
193721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
193892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
1939af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedImm.SrcReg
1940af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1941af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
194292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
194392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
194421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
19457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
19467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
194721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
1948293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1949293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
1950293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
195121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
195221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
195321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
19548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
19558d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
19565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
19575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
19587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
19597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
19607729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
19618d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
19628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
19638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
19648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
19658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1966862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  case k_VectorList:
1967862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    OS << "<vector_list " << VectorList.Count << " * "
1968862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach       << VectorList.RegNum << ">";
1969862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    break;
197021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
1971fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1972fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1973460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
1974460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
1975460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
1976fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1977fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
19783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
19793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
19803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
19813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
19823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
19833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
19843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
19853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
198669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
198769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
19881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
1989bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1990bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1991bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1992bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
19939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1994e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1995e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
19963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
19971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
199818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
19997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
2000d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
2001a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
2002a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
20030c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
20040c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
20050c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
20060c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
20070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
20080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
20090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
20100c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
20110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
20120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
20130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
20140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
201569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
2016b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
2017460a90540b045c102012da2492999557e6840526Jim Grosbach
2018e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
2019e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
2020d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
202119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
202219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
202319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
202419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
202519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
20260d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
20270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
20280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
20290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
20300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
20310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
20320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
20330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
20340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
20350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
20360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
20370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
20380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
20390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
20400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
20410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
20420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
204319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
20440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2045e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
2046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
2047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
2048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
2049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
2050eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
2051e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
2052e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
2053e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
2054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
2055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
2056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
2057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
2058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
2059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
2060e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
2061e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
2062e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
2063e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
2064e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
2065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
2066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
206719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
206819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
206919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
207019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2071e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
2072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
207319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
207419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
207519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
207619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
2077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
2078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
2079e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
2080e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
2081e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
2082e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
2083e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
208419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
208519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
2086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
2087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
20881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
2089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
209019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
209119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
209219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
209319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
209419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
209519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
2096e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
209719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
209819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
2099e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
2100e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
210192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
210292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
2103af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
21040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
210592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
210692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
210792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
21080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
210919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
21100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
21110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
21120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
211350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
211450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
211550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
2116e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
2117e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
2118e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
211950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
21201355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2121e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
21221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
2123e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
212450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
2125d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
212650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
2127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2128e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
2129e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
213050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
213150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
2132e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
2133460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
2134460a90540b045c102012da2492999557e6840526Jim Grosbach  }
2135460a90540b045c102012da2492999557e6840526Jim Grosbach
2136460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
2137460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
2138460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
2139460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
2140460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
2141460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
2142460a90540b045c102012da2492999557e6840526Jim Grosbach
2143460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
2144460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
2145460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2146460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2147460a90540b045c102012da2492999557e6840526Jim Grosbach    if (!MCE) {
2148460a90540b045c102012da2492999557e6840526Jim Grosbach      TokError("immediate value expected for vector index");
2149460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2150460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2151460a90540b045c102012da2492999557e6840526Jim Grosbach
2152460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
2153460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2154460a90540b045c102012da2492999557e6840526Jim Grosbach      Error(E, "']' expected");
2155460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
2156460a90540b045c102012da2492999557e6840526Jim Grosbach    }
2157460a90540b045c102012da2492999557e6840526Jim Grosbach
2158460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
2159460a90540b045c102012da2492999557e6840526Jim Grosbach
2160460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
2161460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
2162460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
216399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
216499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
216550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2166a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2168fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
2169fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
2170fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
2171fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
2172e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
2173e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
2174e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
2175e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
2176e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
2177fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
2178e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2179e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
2180e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2181e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
2182e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
2183e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
2184e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
2185e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
2186e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
2187e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
2188e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
2189e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
2190e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
2191e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2192e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
2193e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
2194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
2195e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
2196e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
2197e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
2198e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
2199e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
2200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
2201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
2202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
2203e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
2204e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
2205e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
2206e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
2207e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2208e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
2209e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2210e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
221189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
221289df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
221389df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
221489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
221589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
221689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
221789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
221889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
221989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
222089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
222189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
222289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
222389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
222489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
222589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
222689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
222789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
222889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
222989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
223089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
223189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
223289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
223389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
223489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
223589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
223689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
223789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
223889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
223989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
224089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
224189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
224289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
224389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
224489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
224589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
224643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2247fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2248fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2249f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
225043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2251e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2252e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2253c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2254c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2255e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2256fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2257e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2258f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2259e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2260e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2261fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2262f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
226543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2266fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2267fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2268f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
226943904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2271fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2272c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2273c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    return MatchOperand_NoMatch;
2274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2277f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2278fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2281f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2282e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2283e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
22849b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// parseCoprocOptionOperand - Try to parse an coprocessor option operand.
22859b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach/// coproc_option : '{' imm0_255 '}'
22869b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
22879b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim GrosbachparseCoprocOptionOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22889b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc S = Parser.getTok().getLoc();
22899b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
22909b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // If this isn't a '{', this isn't a coprocessor immediate operand.
22919b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::LCurly))
22929b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_NoMatch;
22939b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '{'
22949b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
22959b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCExpr *Expr;
22969b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
22979b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (getParser().ParseExpression(Expr)) {
22989b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "illegal expression");
22999b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
23009b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
23019b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
23029b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (!CE || CE->getValue() < 0 || CE->getValue() > 255) {
23039b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    Error(Loc, "coprocessor option must be an immediate in range [0, 255]");
23049b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
23059b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  }
23069b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  int Val = CE->getValue();
23079b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
23089b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  // Check for and consume the closing '}'
23099b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
23109b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach    return MatchOperand_ParseFail;
23119b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  SMLoc E = Parser.getTok().getLoc();
23129b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Parser.Lex(); // Eat the '}'
23139b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
23149b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  Operands.push_back(ARMOperand::CreateCoprocOption(Val, S, E));
23159b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach  return MatchOperand_Success;
23169b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach}
23179b8f2a0b365ea62a5fef80bbaab3cf0252db2fcfJim Grosbach
2318d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2319d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2320d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2321d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2322d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2323d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2324d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2325d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2326d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2327d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2328d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
2329d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2330d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2331d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2332d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2333d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2334d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2335d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2336d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2337d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2338d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2339d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2340d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
234150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
23421355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
234318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2344a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2345e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2346d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2347d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
234816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2349d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2350d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2351d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2352d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2353d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2354d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2355d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  MCRegisterClass *RC;
2356d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2357d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2358d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2359d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2360d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2361d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2362d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2363d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2364e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2365d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2366d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // space for that many.
2367d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2368d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Store the first register.
2369d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2370d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2371d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2372d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2373d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2374d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2375d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2376d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2377d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      Parser.Lex(); // Eat the comma.
2378d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2379d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2380d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2381d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2382d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2383d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2384d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2385d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2386d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2387d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2388d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2389d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2390d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2391d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2392d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2393d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2394d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2395d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2396d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2397d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2398d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2399d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2400d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2401d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2402d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2403d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2404d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
24052d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2406d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2407d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2408d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2409d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2410d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg))
2411d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2412d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2413d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2414d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2415d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2416d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2417d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2418d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2419d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2420d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2421d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2422d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2423d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2424d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2425e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
242650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
242750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2428d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2429d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
2430862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach// parse a vector register list
2431862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2432862019c37f5b5d76e34eeb0d5686e617d544059fJim GrosbachparseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2433862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if(Parser.getTok().isNot(AsmToken::LCurly))
2434862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_NoMatch;
2435862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2436862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc S = Parser.getTok().getLoc();
2437862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '{' token.
2438862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
2439862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2440862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  int Reg = tryParseRegister();
2441862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Reg == -1) {
2442862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(RegLoc, "register expected");
2443862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2444862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2445862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2446862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned FirstReg = Reg;
2447862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  unsigned Count = 1;
2448862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  while (Parser.getTok().is(AsmToken::Comma)) {
2449862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Parser.Lex(); // Eat the comma.
2450862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    RegLoc = Parser.getTok().getLoc();
2451862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    int OldReg = Reg;
2452862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Reg = tryParseRegister();
2453862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg == -1) {
2454862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "register expected");
2455862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
2456862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
2457862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // vector register lists must also be contiguous.
2458862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2459862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    // VFP register classes have the enum sorted properly.
2460862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    if (Reg != OldReg + 1) {
2461862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      Error(RegLoc, "non-contiguous register range");
2462862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach      return MatchOperand_ParseFail;
2463862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    }
2464862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2465862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    ++Count;
2466862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2467862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2468862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2469862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly)) {
2470862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    Error(E, "'}' expected");
2471862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach    return MatchOperand_ParseFail;
2472862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  }
2473862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Parser.Lex(); // Eat '}' token.
2474862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
2475862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E));
2476862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach  return MatchOperand_Success;
2477862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach}
2478862019c37f5b5d76e34eeb0d5686e617d544059fJim Grosbach
247943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
2480f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
248143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2482706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2483706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2484706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2485706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
2486706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2487706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
2488706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
2489706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
2490032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
2491706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
2492032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
2493706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
2494706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
2495032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
2496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
2497032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
2498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
2499706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
2500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
2501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
2503f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2505706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
2507f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2508706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
2509706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
251043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
2511a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
251243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2513a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2514a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
2517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
25182dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
25192dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
2520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
25212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
25222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
25232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
25242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
25252dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
25262dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
25272dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
25282dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
25292dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
25302dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
25312dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
25322dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
25332dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
25342dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
25352dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
2536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2539a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
2540a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
2541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
2542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
254343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
2544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
254543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
2550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2551acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
2552acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
2553acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
2554acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
2555acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
2556acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
2557acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
2558acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
2559acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
2560acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
2561acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
2562acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
2563acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
2564acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
2565acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
2566acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
2567acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
2568acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
2569acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2570acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
2571acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
2572acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2573acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
2574acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
2575acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
2576acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2577acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
2578acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2579acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
2580acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
2581acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2582584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
2583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
2584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
2585b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
2586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
2587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
2588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
2590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
2591584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
2593584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
2595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
2596b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
2597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
2598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
2599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
2600584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
26014b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
2602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
2603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
2604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
2605bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
26064b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
2607584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
260856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
260956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
2610584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
2611584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
2612584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
2613584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
2614584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
2615584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
2616584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
2617584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2618584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
2619584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
2620584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
2621584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
2622584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
2623584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
2624584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
2625584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
2626584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
26277784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // Special register without flags is NOT equivalent to "fc" flags.
26287784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // NOTE: This is a divergence from gas' behavior.  Uncommenting the following
26297784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // two lines would enable gas compatibility at the expense of breaking
26307784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // round-tripping.
26317784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //
26327784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  // if (!FlagsVal)
26337784f1d2d8b76a7eb9dd9b3fef7213770605532dOwen Anderson  //  FlagsVal = 0x9;
2634584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2635584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2636584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
2637584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
2638584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2640584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2641584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
2642a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
2643a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2644f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2645f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
2646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
2647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2648f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
2653f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
2654f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
2655f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
2656f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2657f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2658f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2659f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
2660f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2661f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
2662f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2663f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2664f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2665f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2666f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
2667f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2668f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
2669f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
2670f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2671f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
2672f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2673f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2674f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2675f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
2676f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
2677f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2678f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2679f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
2680f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
2681f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
2682f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2683f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2684f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2685f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
2686f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2687f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
2688f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
2689f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2690c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2691c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2692c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2693c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
2694c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2695c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2696c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2697c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2698c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
2699c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
2700c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
2701c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
2702c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
2703c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2704c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
2705c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2706c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2707c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2708c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
2709c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
2710c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
2711c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
2712c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
2713c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2714580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
2715580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
2716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
2717580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
2718580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
2719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2721580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
2722580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
2723580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2724580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2725580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2726580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2727580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
2728580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
2729580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
2730580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
2731580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
2732580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
2733580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
2734580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2735580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2736580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2737580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
2738580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2739580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
2740580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2741580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2742580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2743580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2744580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
2745580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2746580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
2747580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2748580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2749580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
2750580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2751580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2752580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2753580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
2754580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
2755580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2756580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2757580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2758580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
2759580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
2760580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2761580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
2762580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
2763580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2764580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
27650afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
27660afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
27670afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
27680afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
27690afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
2770580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
2771580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
2772580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2773580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
2774580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
2775580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2776580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
2777580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2778580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2779580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
2780580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
2781580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2782580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
2783580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
2784580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
27857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
27867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
27877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
27887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
27897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
27907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
27917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
2792326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2793326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
27947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
2795326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
2796326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
27977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
27987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
27997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
28007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
28017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
28027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
28037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
28047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
28057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
28067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
28077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
28087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
28097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
28107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
28117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
28127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
28137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
28147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
28157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
28167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
28177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
28187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
28197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
28207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
28217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
28227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
28237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
28247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
28257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
28267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
28277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
28287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
28297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
28307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
28317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
28327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2833293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2834293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2835293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
2836293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
2837293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2838293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2839293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2840293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2841293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2842293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2843293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
2844293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2845293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
2846293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2847293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2848293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2849293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
2850293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2851293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
2852293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2853293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2854293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2855293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
2856293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
2857293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
2858293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
2859293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2860293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2861293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2862293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2863293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
2864293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
2865293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
2866293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2867293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2868293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2869293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2870293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2871293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2872293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2873293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2874293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2875293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
2876293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
2877293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2878293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2879293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2880293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
2881293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2882293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
2883293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2884293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2885293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2886293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
2887293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
2888293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
2889293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
2890293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2891293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2892293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2893293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2894293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
2895293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2896293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
2897293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
2898293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
29007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
29017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2902f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
2903f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
2904f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
29057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
29067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
29087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
29097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
29107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
29117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
291216578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
29147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
29157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
29167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
29177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
29187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
291916578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
29207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
29217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
29227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
29237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
29247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
29257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
29267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
29277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
29287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
29297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
29307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
29317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2932f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
2933f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
29340d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
29350d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
29360d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
29370d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
29380d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
2939f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
2940f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
2941f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
29427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
29437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
29447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
29457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2946251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2947251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2948251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2949251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
2950251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
2951251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
2952251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
2953251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
2954251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
2955251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2956251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
2957251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
2958251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
2959251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
2960251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
2961251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2962251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
2963251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
2964251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
2965251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
2966251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
2967251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2968251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
2969251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
2970251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2971251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
2972251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
2973251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
2974251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2975251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
2976251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
2977251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
2978251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
2979251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
2980251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
2981251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2982251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
2983251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
2984251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2985251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
2986251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2987251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2988251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2989251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
2990251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
2991251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
2992251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
2993251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
2994251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2995251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
2996251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
2997251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
2998251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2999251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3000251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
3001251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
3002251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
3003251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
3004251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
3005251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
3006251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
3007251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
3008251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
3009251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3010251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
3011251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
3012251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3013251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
3014251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
3015251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
3016a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
3017a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3018a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3019a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3020a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
3021a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3022a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3023a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3024a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3025a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3026a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3027a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3028a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3029a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3030a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3031a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3032a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3033a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3034a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
3035a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3036a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3037a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
3038a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
3039a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3040a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
3041a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
3042a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
3043a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3044a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
3045a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
3046a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
3047a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
3048a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3049a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
3050a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
3051a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
3052eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3053eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3054eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3055eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
3056eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3057eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3058eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3059eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3060eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
3061eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3062eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3063eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3064eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3065eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
3066eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
3067eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
3068ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
3069ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3070ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3071ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
3072ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
3073ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3074ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
3075ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3076ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3077ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
3078ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3079ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
3080ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
3081ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
30821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3083ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3084ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3085ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
30861355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3087ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3088ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3089ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
3090ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3091ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3092ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
30937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3094ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3095ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3096ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3097ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
30989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
30999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
31009ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
31019ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
31029ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
31039ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
31049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
31059ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
31069ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
31079ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
31089ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
31099ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
31109ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
31119ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
31129ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
31139ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
31149ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3115548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
3116548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3117548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3118548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
3119548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
3120548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3121548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
3122548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3123548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3124548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
3125548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3126548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
3127548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
3128548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
31291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
3130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
31331355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
3134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3136ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
3137548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3138548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
3139548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
31407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
31417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
31427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
31437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
31447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
31457b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
31467b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
31477b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
31487b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
31497b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
31507b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
31517b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
31527b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
31537b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
31547b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
31557b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
31567b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
31577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
31587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
31597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
31607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
31617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
31627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
31637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3164ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
31657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
31667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
31677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
31687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
31697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
31707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
31717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3172ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3173ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
3174ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
3175ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
31767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
3177ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3178ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3179ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
31807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
31817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
31827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3183aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3184ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3185ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
31867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
31877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
31887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
31897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
31907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
31917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
31927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
31937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
3194aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
31957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
31967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
31977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
31987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
31997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
32007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
32017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
32027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
32037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
32047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
32057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
32067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
32077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
32087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
32097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3210ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3211ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3212ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3213ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
32147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
3215ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3216ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
3217ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
32187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
32197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3220ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
3221ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
32227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
3223ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
32247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
32257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
32267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
32277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
32287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
3229ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3230ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
3231ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
3232ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
32332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
32342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
32352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
32362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
32372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
32382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
32392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
32402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
32412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
32422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
32432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
32442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
32452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
32462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
32472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
32482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
32492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
32502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
325114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
325214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
325314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
325414605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
325514605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
325614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
325714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
325814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
325914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
326014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
326114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
326214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
326314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
326414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
326514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
326614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
326714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
326814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
3269623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
3270623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
3271623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
3272623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
3273623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
3274623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3275623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
3276623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
3277623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
3278623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
3279623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
3280623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
3281623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
3282623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
328388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
328488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
328588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
328688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
328788ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
328888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
328988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
329088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
329188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
32927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
32937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
32947a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
32957a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
329688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
32977a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
329888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
329988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
330088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
330188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
330288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
33037a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // If we have a three-operand form, use that, else the second source operand
33047a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // is just the destination operand again.
33057a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  if (Operands.size() == 6)
33067a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
33077a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  else
33087a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    Inst.addOperand(Inst.getOperand(0));
330988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
331088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
331188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
331288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
3313623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
3314e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
33159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
331650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
33177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3318762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
331918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
3320a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
3321762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
3322b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
3323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
332418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
33251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
33267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
33277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
3328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
33290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
33300571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
33310571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
33327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
33330571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
33347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
3335762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
3336b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
3337a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
33387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
333957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             0, 0, false, S, E));
334003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
3341fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
3342fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
3343fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
3344fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3345fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
3346fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
3347fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
33487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
33497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
335050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
33517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
33527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
335350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
335457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a ':', it's an alignment specifier.
335557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  if (Parser.getTok().is(AsmToken::Colon)) {
335657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat the ':'.
335757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
335857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
335957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCExpr *Expr;
336057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (getParser().ParseExpression(Expr))
336157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach     return true;
336257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
336357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // The expression has to be a constant. Memory references with relocations
336457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // don't come through here, as they use the <label> forms of the relevant
336557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // instructions.
336657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
336757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (!CE)
336857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error (E, "constant expression expected");
336957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
337057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    unsigned Align = 0;
337157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    switch (CE->getValue()) {
337257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    default:
337357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "alignment specifier must be 64, 128, or 256 bits");
337457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 64:  Align = 8; break;
337557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 128: Align = 16; break;
337657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    case 256: Align = 32; break;
337757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
337857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
337957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Now we should have the closing ']'
338057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    E = Parser.getTok().getLoc();
338157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
338257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      return Error(E, "']' expected");
338357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Parser.Lex(); // Eat right bracket token.
338457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
338557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // Don't worry about range checking the value here. That's handled by
338657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // the is*() predicates.
338757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0,
338857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, Align,
338957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
339057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
339157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
339257dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    // operand.
339357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
339457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
339557dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach      Parser.Lex(); // Eat the '!'.
339657dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    }
339757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
339857dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach    return false;
339957dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  }
340057dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach
340157dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach  // If we have a '#', it's an immediate offset, else assume it's a register
34027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset.
34037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
34047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '#'.
34057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
340650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
34070da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
34087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
34097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
34107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
341105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
34127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
34137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
34147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
34157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
34167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
34177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
34187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
34190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
34200da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
34210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
34220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
34230da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
34247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
34257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
34267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
34277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
34287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
342905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
34307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
34317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
34327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
343357dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             ARM_AM::no_shift, 0, 0,
343457dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                             false, S, E));
3435a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
34367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
34377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
34387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
34397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
34407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
3441762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
34427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
34437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
34449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
3445d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
34467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
34477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
34487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
34497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
34507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
34517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
34527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
34537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
34547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
34559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
34567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
34577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
34587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
34597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
34607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
34617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
34627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
34630d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
34647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
34657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
34660d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
34677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
34689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
346916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
34707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
34717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
34727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
34737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
34747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
34757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
34767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
347757dcb85a30133a9bc008f0b9ead81be03a23521eJim Grosbach                                           ShiftType, ShiftImm, 0, isNegative,
34787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
34797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3480f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
3481f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
3482f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
3483f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3484f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
3485f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
34869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
34879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
34889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
34899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
34907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
3491a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
3492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
34937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
34947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
34957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
34967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
349718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3498a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3499a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
350038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
3501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
35020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
3503a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
35040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
3505a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
35060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
3507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
35080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
3509a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
35100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
3511a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
35127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
3513b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
3514a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
35157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
35167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
35177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
35187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
35197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
35207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
35217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (HashTok.isNot(AsmToken::Hash))
35227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
35237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
35249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
35257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
35267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
35277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
35287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
35297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
35307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
35317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
35327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
35337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
35347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
35357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
35367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
35377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
35387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
35397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
35407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
3541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
3543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
3544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
35459d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
35469d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
35479d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
35489d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
35499d39036f62674606565217a10db28171b9594bc7Jim Grosbach
35509d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash))
35519d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
35520e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
35530e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // Disambiguate the VMOV forms that can accept an FP immediate.
35540e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <sreg>, #imm
35550e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f64 <dreg>, #imm
35560e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <dreg>, #imm  @ vector f32x2
35570e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.f32 <qreg>, #imm  @ vector f32x4
35580e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  //
35590e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // There are also the NEON VMOV instructions which expect an
35600e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // integer constant. Make sure we don't try to parse an FPImm
35610e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // for these:
35620e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  // vmov.i{8|16|32|64} <dreg|qreg>, #imm
35630e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  ARMOperand *TyOp = static_cast<ARMOperand*>(Operands[2]);
35640e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach  if (!TyOp->isToken() || (TyOp->getToken() != ".f32" &&
35650e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach                           TyOp->getToken() != ".f64"))
35660e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach    return MatchOperand_NoMatch;
35670e387b2877e4eebeedfcb26b08253f9c1b946035Jim Grosbach
35689d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
35699d39036f62674606565217a10db28171b9594bc7Jim Grosbach
35709d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
35719d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
35729d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
35739d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
35749d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
35759d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
35769d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
35779d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
35789d39036f62674606565217a10db28171b9594bc7Jim Grosbach    APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
35799d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
35809d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
35819d39036f62674606565217a10db28171b9594bc7Jim Grosbach    IntVal ^= (uint64_t)isNegative << 63;
35829d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int Val = ARM_AM::getFP64Imm(APInt(64, IntVal));
35839d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
35849d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val == -1) {
35859d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("floating point value out of range");
35869d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
35879d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
35889d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
35899d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
35909d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
35919d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
35929d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
35939d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
35949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
35959d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("encoded floating point value out of range");
35969d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
35979d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
35989d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
35999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
36009d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
36019d39036f62674606565217a10db28171b9594bc7Jim Grosbach
36029d39036f62674606565217a10db28171b9594bc7Jim Grosbach  TokError("invalid floating point immediate");
36039d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
36049d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
36059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
36069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
36071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
3608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
3609762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
3610fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
3611fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
3612fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
3613f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3614f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
3615fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
3616f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
3617f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
3618f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
3619f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
3620f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
3621fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
3622a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
3623146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
3624146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
362550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
362619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
36275cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
36281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
362950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
36300d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
363119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
36320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
363319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
363419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
36355cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
36365cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
36375cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
36385cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
36395cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
36405cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
3641e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
3642e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
3643e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
364419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
364567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
364667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
3647515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
3648515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
3649515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
3650762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
3651515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
365250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
3653762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
365450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
365550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
365650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
3657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
36581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
3659d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
36601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
366163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
3662079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
3663079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
3664762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
3665b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
366663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3667515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
3668515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
366950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
367063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
367163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (!CE) {
367263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      Error(S, "constant expression expected");
367363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      return MatchOperand_ParseFail;
367463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
367563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    int32_t Val = CE->getValue();
367663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (isNegative && Val == 0)
367763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
3678762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
367950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
368050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
368163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
36829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
36839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
36847597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
36857597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
36867597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
36871355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
36889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
36899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
36907597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
36917597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
36929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
36939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
36947597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
36957597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
36969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
36977597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
36989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
36999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
3700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
3701a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
3702a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
37031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
37047597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
37051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
37067597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
37079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
37089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
37098a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
37109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
37119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
37129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
37139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
37149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
37159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
37169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
37179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
37189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
37197597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
37209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
37217597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
37229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
37239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
37249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
37259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
37269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
37279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
37289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
37299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
37309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
37319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
37329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
37339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
37349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
37359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
3736352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
3737352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
3738352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
3739badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
374089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
37411355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
37425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
37435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
374489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
374589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
3746352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
3747352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
3748a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
3749352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
3750badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
3751352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
3752352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
37535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
37545f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
37555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
37565f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
37575f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
37585f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
37595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
37605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
3761352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
3762badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
37633f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
37643f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
3765ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
376671725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
376704d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
37682f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
37693f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
37703f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
37713f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
37723f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
37733f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
37743f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
37753f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
37763f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
37773f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
37783f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
37793f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
37803f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
37813f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
37823f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
37833f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
37843f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
37853f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
37863f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
37873f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
37883f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
37893f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
37903f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
37913f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
379252925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
3793345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
3795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
3796352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
379700f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
37985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
37995f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
38005f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
3801e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
3802e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
3803352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
3804352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
3805352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
3806352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
3807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
3808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
3809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
3810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
3811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
3812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
3813a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
3814a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
3815a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
3816a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
3817a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
3818a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
3819a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
3820a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3821a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
382289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
382389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
382489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
382589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
382689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
382789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
3828352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
3829352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
38303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
38313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
38323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
38333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
38343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
3835fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
38361355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
3837fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
3838eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
3839eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
38403443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
3841eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
3842d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
3843eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
3844d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
38453443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
3846d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
3847d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
3848eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
3849fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
3850eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
38513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
3852eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
3853eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
3854eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
3855eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
3856ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
3857ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
38580780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
38592bd0118472de352745a2e038245fab4974f7c87eJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw" ||
38602bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "ldc2" || Mnemonic == "ldc2l" ||
38612bd0118472de352745a2e038245fab4974f7c87eJim Grosbach        Mnemonic == "stc2" || Mnemonic == "stc2l") && !isThumb()) ||
38624af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
38634af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
38641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
38653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
3866fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
38673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
3868fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
3869fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
3870fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
387163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
3872fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
3873fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
3874badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
3875badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3876d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
3877d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
387820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
387920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
3880d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3881d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
3882d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
3883d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
3884d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
3885d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
3886d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
3887d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
3888d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
38898adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
3890d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
3891d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
3892d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3893d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
38943912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
38953912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
38963912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
38973912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
38983912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
38993912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
39003912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
39013912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
390272f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
390320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
390420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
390520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
3906f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
3907f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
3908f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
390972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
391072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
391172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
391220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
391320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
391420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
391572f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
3916f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
3917f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
391820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
391920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
392020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
3921f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
3922f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
392320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
392420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
392520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
392620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
392720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
392820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
392920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
393020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // check against T3.
393120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
393220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
393320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
393420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
393520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
393620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
393720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
393864944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
393920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
394020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
394120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
394220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
394320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
394420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
394520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
394620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
394720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
394864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
394964944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
395064944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
395164944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
395264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
395364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
395464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
395564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
395664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
395764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
395864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
395964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
396064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
396164944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
396264944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
396364944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
396464944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
396564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
396664944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
396764944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
396864944f48a1164c02c15ca423a53919682a89074cJim Grosbach
396964944f48a1164c02c15ca423a53919682a89074cJim Grosbach
397020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
3971f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
3972f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
3973f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
3974f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
3975f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
3976f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
3977f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
397872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
397972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
398072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
398172f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
39823912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
3983d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
3984d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
3985d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3986badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
3987badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
3988badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3989badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
3990badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
3991ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
3992badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3993352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
3994352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
3995a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
3996352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
399789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
39981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
399989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
4000badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
40010c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
40020c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
40030c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
40040c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
40050c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
40060c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
4007ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
4008ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
400989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
401089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
401189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
401289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
401389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
401489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
4015f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
4016f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
4017f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
4018f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
4019f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
402089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
402189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
402289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
402389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
402489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
4025f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
402689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
402789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
402889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
402989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
403089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
4031f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
403289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
403389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
4034ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
4035ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
40369717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
40373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
40383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
40393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
40403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
40413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
40423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
40433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
40443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
40451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
40463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
404733c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
404833c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
404933c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
405033c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
4051ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
405233c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
405333c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
4054c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
4055c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
4056c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
4057c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
4058c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
4059c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
4060c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
406133c16a27370939de39679245c3dff72383c210bdJim Grosbach
40623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
4063f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
4064f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
40653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
4066f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
4067f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
40683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
40693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
40703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
4071f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
4072f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
40733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
4074f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
4075badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
4076345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
4077a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
4078a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
4079a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
4080a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
4081a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
4082a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
4083a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
4084345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
40855747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
40865747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
40875747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
4088a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
4089a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
40904d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // For now, we're only parsing Thumb1 (for the most part), so
40914d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // just ignore ".n" qualifiers. We'll use them to restrict
40924d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // matching when we do Thumb2.
409381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
409481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
409581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
409681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
40975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
40985747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
40995747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
41005747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
41021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
4103cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
4104cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
4105cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
4106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
4108b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
4109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4110a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
41111355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
4112cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
4113cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
4114cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
4115a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
4116a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
411716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4118cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4119186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
4120cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
4121186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
4122cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
4123146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
412434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
4125ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4126d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
4127d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
4128d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
412920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
413020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
413120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
413220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
413320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
4134ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4135ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
4136ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
4137ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
4138ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
4139cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
4140cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
4141cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
414221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
414321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
4144cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
4145cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
4146cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
4147cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
4148cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
4149cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
4150857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
4151857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
4152857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
4153857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
4154857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
4155857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
4156857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4157857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4158857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4159857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
4160857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
4161857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
416268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
416368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
416468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
416568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
416668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
416768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
416868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
416968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
417068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
417168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
417268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4173857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
4174857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
4175857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
4176934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
4177934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // end. Convert it to a token here.
4178934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
4179934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
4180934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
4181934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
4182934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    if (CE && CE->getValue() == 0) {
4183934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
4184934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
4185934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
4186934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
4187934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
4188934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
41899898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
4190ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4191ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4192189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
4193aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
4194aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
4195aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
4196aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
4197aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
4198aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
4199aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
4200aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
4201aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
4202aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
4203aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
4204aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
4205aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
4206aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
4207aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
4208aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
4209aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
4210aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
421176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
421276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
421376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
421476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
421576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
421676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
421776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
421876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
421976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
422076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
422176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
4222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
4223f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
4224f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
4225f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
4226f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[];
4227f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
4228f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) {
4229f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
4230f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
4231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4232189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
4233189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
4234189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
4235189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
4237f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
4238f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
4239b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
4240b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // being allowed in IT blocks, but not being predicable.  It just always
4241b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
4242b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
4243f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
4244f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
4245f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
4246f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
4247a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
4248f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
4249f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
4250f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
4251f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
4252f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
4253f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
4254f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
4255f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
4256f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
4257f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
4258f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
4259f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
4260f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
4261f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
4262f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
4263f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
4264f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
4265c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
4266f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
4267f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
426851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
426951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
4270f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
4271f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4272189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
42732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
42742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
42752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
4276189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
4277189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
4278189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
4279189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4280189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
4281189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
4282189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
4283189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
4284189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
428514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
428614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
428714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
428814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
428914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
429014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
429114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
429214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
429314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
429453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
429553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
4296189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
4297189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
4298189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
4299189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
4300189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
430114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
4302189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
4303189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
4304189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
4305fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
4306fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
4307fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
4308fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
4309fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
4310fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
4311fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
4312fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
431300c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
4314fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
431593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
431676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
431776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
431876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
431976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
432076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
432193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
432293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
432393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
43247260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
43257260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
43267260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
4327aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
432876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
4329aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
4330aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
433193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
433276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
433393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
433493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
433576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
433676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
4337aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
43387260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
43397260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
43407260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
434193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
434293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
434393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
434476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
434576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
434676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
434776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
434876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
434976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
435076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
43516dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
4352aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
4353aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
4354aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
4355aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
43566dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
43576dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
43586dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
4359aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
4360aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
4361aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
4362aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
43636dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
43646dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
43651e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
43661e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
43678213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
43681e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
43691e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
43701e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
43711e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
4372189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
4373189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
4374189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
4375189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
4376189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
4377f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser::
4378f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
4379f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4380f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
4381f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
4382f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
4383f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
4384f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
4385f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
4386f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
4387f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
4388f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
4389f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
4390f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
4391f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
4392f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
4393f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
4394f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
4395f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
4396f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
4397f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
4398f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
4399f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
4400f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
4401f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
4402f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
4403f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
4404f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
4405f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
4406f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
4407f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
4408f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
4409f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
4410f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
4411f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
4412f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
4413f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
441489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
44150f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
44160f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
44170f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
44180f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
44190f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
442089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
442189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
4422f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
4423f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
4424f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
4425f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
4426f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
4427f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
4428f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
4429f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
443051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
443151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
443251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
443351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
443451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
443551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
443651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
443751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
443851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
443951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
4440c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
4441a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
4442a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
4443c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
4444c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
4445395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
4446395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
4447395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL)
4448395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
44493ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
445076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
445176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
445276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
445376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
445476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
445576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
445676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
445776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
445876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
445976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
446076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
446176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
446276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
446376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
446476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
446576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
446676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
446776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
446876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
446976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
447076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
447176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
447276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
447376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
44748213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
44758213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
44768213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
44778213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
44788213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
44798213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
44808213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
44818213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
44828213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
44838213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
44848213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
44858213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
44868213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
44871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
44881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
44891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
44901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
44911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
4492c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
4493c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
4494c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
44951ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
44961ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
44971ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
44981ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
44991ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
45001ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
45011ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
45021ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
45031ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
45041ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
45051ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
45061ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
45071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
45081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
45091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
45101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
45111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
45121ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
45131ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
45141ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
45151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
45161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
45171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
45181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
45191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
45201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
45211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
45221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
45231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
45241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
45251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
45261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
45271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
45281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
4529326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
453050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
453150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
453250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
4533326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
4534326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
4535326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
4536326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
4537326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
4538326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
4539326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
454050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
454150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
454250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
454350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
454450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
454550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
454650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
454750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
4548326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
4549326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
4550326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
4551326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
4552326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
4553326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
4554326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
4555326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
4556326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
4557326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
4558326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
455989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
456089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
456189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
456289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
456389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
456489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
456589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
456689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
456789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
4568f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
4569f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
457089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
457189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
457289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
457389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
457489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
457589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
457689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
4577f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4578f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
4579f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
4580f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
4581f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
4582f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
4583f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
4584f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
458589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
458689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
4587f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
4588f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
4589f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
459047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
459147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
459247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
4593194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
4594194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Opc);
459547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
459647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
459747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
459847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
459947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
460047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
460147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
460247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
460347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
460447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
460547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
460647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
460747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
460847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
460947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
461047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
4611f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
4612f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
461347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
4614f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
4615f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
4616f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
461747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
4618194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
4619194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
4620194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
4621194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
4622194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
4623194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
4624194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
46254ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
4626194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
4627194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
4628194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
462947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
463047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
463147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
4632fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
4633fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
4634fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4635fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
4636fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
4637fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
463819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
4639193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
4640193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
464119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
4642e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
4643189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
4644189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
4645a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
4646a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
4647a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
4648a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
4649189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
4650a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
4651189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
4652f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
4653f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // encoding is selected.
4654f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    processInstruction(Inst, Operands);
4655f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
4656a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
4657a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
4658a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
4659a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
4660a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
4661fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
4662fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
4663e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
4664e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4665e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
4666e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
4667e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
4668e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
4669e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
4670e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
467116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4672e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
4673e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
4674e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
467516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4676e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
4677e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
4678e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
467947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
4680b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
468188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
468288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
4683f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
4684f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
468547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
468647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
4687194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
4688194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
4689194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
4690194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
4691fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
469216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4693c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
4694146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
4695fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
4696fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
46971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
4698ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
4699ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
4700ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
47011355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
4702515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
47031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
4704515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
47051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
4706515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
47071355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
4708515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
47091355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
4710ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
4711ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4712ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
4714ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
47151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4716ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4717ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
4718ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
4719ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
4720ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
4721ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4722aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
4723ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4724ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
4725ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
472616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4727ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
4728ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
4729ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
4730b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
4731ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
4732ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
4733ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4734b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4735ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
4736ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4737ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
4739515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
47401355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
4741515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
4742515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
4743b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4745515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
4746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
4747515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
4748515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4749515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4750515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
47511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
4752515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
47531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
47546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
47556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
47566469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
47576469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
47586469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
47596469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
47606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
47616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
47626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
47636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
47646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
47656469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
47666469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
47676469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4768515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
4769515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
4770b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
47726469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
47736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
47746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
47756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
47766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4777642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
4778642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
4779642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
4780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4781515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
47831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
4784515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
47851355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
478618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4787515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4788515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
478938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
479058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
4791b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
479258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
47939e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
4794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
4795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
4796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4797515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
479818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4799b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4800515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4801515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
4802515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
4803515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4804515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4805515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
48061355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
4807515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
48081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
480918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
4811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
481218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
481358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
4814b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
481558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
4816b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4817515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
4818515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
4819515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4820515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
482118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4822b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4823515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
482432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
482598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
4826ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
482798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
482832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
482998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
4830ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
483198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
4832eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
48332a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
4834515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4835515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4836515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
483790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
483890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
48399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
4840ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
484194b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
484294b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
484390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
4844ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
48453483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
48460692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
48470692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
48483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
4849