ARMAsmParser.cpp revision f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8
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*>&);
14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1428bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1468bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
147f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
155c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
156580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
160251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
1619d39036f62674606565217a10db28171b9594bc7Jim Grosbach  OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
162ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
163ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
164a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
165a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
166a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
167a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
168eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
169eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
170ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
171ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
173ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1749ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1759ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
176548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
177548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
179ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1807b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1817b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
1912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
19214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
19314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
194623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
195623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
19688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
19788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
198189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
199189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
200189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
201f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  void processInstruction(MCInst &Inst,
202f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
203d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
204d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
205189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
206ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
20747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
208194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
209f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
210194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
211194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
21247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
21347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
214ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
21594b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
216ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
21732869205052430f45d598fba25ab878d8b29da2dEvan Cheng
218ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
219ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
220f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
221f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
222f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
223ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
228189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2301355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
23147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
23247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2341355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
236ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
23716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
23816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
241a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
243146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
24521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CondCode,
24621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CCOut,
24721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ITCondMask,
24821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocNum,
24921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_CoprocReg,
25021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Immediate,
25121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_FPImmediate,
25221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MemBarrierOpt,
25321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Memory,
25421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_PostIndexRegister,
25521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_MSRMask,
25621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ProcIFlags,
257460a90540b045c102012da2492999557e6840526Jim Grosbach    k_VectorIndex,
25821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Register,
25921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RegisterList,
26021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_DPRRegisterList,
26121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_SPRRegisterList,
26221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedRegister,
26321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShiftedImmediate,
26421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_ShifterImmediate,
26521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_RotateImmediate,
26621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_BitfieldDescriptor,
26721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    k_Token
268a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
269a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
270762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
27124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
272a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
273a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2758462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
2778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
279fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
280fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
28389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
28489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
28589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
28689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
28789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
28889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
28989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
29089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
293a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
294a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
301a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3078155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
308460a90540b045c102012da2492999557e6840526Jim Grosbach      unsigned Val;
309460a90540b045c102012da2492999557e6840526Jim Grosbach    } VectorIndex;
310460a90540b045c102012da2492999557e6840526Jim Grosbach
311460a90540b045c102012da2492999557e6840526Jim Grosbach    struct {
312cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
313cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
31416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3159d39036f62674606565217a10db28171b9594bc7Jim Grosbach    struct {
3169d39036f62674606565217a10db28171b9594bc7Jim Grosbach      unsigned Val;       // encoded 8-bit representation
3179d39036f62674606565217a10db28171b9594bc7Jim Grosbach    } FPImm;
3189d39036f62674606565217a10db28171b9594bc7Jim Grosbach
3196a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
3270d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      unsigned ShiftImm;      // shift for OffsetReg.
3287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
3300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
333f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
334f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
335f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
339580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
340e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
341580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
342e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
343e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
344e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
345e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
346e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
347af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
34892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
34992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
35092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
35192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
352af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
356293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
357293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
358293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
359293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
360a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
36116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
362146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
363146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
364762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
365762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
366762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
368762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
36921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CondCode:
3708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
3718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
37221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ITCondMask:
37389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
37489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
37521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Token:
3768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
377762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
37821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CCOut:
37921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Register:
380762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
38221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RegisterList:
38321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_DPRRegisterList:
38421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_SPRRegisterList:
38524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
3868d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
38721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocNum:
38821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_CoprocReg:
389fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
390fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
39121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Immediate:
392762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
393762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
39421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_FPImmediate:
3959d39036f62674606565217a10db28171b9594bc7Jim Grosbach      FPImm = o.FPImm;
3969d39036f62674606565217a10db28171b9594bc7Jim Grosbach      break;
39721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MemBarrierOpt:
398706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
399706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
40021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_Memory:
401762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
402762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
40321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_PostIndexRegister:
4047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
4057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
40621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_MSRMask:
407584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
408584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
40921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ProcIFlags:
410a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
4110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
41221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShifterImmediate:
413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
4140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
41521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedRegister:
416af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
417e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
41821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_ShiftedImmediate:
419af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
42092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
42121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_RotateImmediate:
4227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
42421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    case k_BitfieldDescriptor:
425293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
426293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
427460a90540b045c102012da2492999557e6840526Jim Grosbach    case k_VectorIndex:
428460a90540b045c102012da2492999557e6840526Jim Grosbach      VectorIndex = o.VectorIndex;
429460a90540b045c102012da2492999557e6840526Jim Grosbach      break;
430762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
431762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
43216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
434762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
437a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4388462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
43921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_CondCode && "Invalid access!");
4408462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4418462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4428462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
443fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
44421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_CoprocNum || Kind == k_CoprocReg) && "Invalid access!");
445fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
446fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
447fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
448a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
44921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Token && "Invalid access!");
450a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
453a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
45421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_Register || Kind == k_CCOut) && "Invalid access!");
4557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
456a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
457a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4585fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
45921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert((Kind == k_RegisterList || Kind == k_DPRRegisterList ||
46021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach            Kind == k_SPRRegisterList) && "Invalid access!");
46124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
4628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
4638d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
464cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
46521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_Immediate && "Invalid access!");
466cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
467cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
468cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
4699d39036f62674606565217a10db28171b9594bc7Jim Grosbach  unsigned getFPImm() const {
47021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_FPImmediate && "Invalid access!");
4719d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return FPImm.Val;
4729d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
4739d39036f62674606565217a10db28171b9594bc7Jim Grosbach
474460a90540b045c102012da2492999557e6840526Jim Grosbach  unsigned getVectorIndex() const {
475460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(Kind == k_VectorIndex && "Invalid access!");
476460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val;
477460a90540b045c102012da2492999557e6840526Jim Grosbach  }
478460a90540b045c102012da2492999557e6840526Jim Grosbach
479706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
48021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MemBarrierOpt && "Invalid access!");
481706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
482706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
483706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
484a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
48521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_ProcIFlags && "Invalid access!");
486a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
487a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
488a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
489584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
49021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    assert(Kind == k_MSRMask && "Invalid access!");
491584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
492584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
493584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
49421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocNum() const { return Kind == k_CoprocNum; }
49521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCoprocReg() const { return Kind == k_CoprocReg; }
49621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCondCode() const { return Kind == k_CondCode; }
49721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isCCOut() const { return Kind == k_CCOut; }
49821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITMask() const { return Kind == k_ITCondMask; }
49921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isITCondCode() const { return Kind == k_CondCode; }
50021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isImm() const { return Kind == k_Immediate; }
50121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isFPImm() const { return Kind == k_FPImmediate; }
502a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
50321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
504a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
505a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
506a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
507a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
508a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
509a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
51072f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
51121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
51272f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
51372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
51472f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
51572f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
51672f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
51772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
51872f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
51921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
52072f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
52172f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
52272f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
52372f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
52472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
52572f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
5266b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
52721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
5296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
5336b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
53483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
53521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
53683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
53783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
53883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
53983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
54083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
54183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
54283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
54321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
54483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
54583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
54683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
54783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
54883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
54983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
5507c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
55121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5527c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
5537c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5547c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
5557c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
5567c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
5577c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
558f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
55921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
560f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
561f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
562f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
563f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
564f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
565f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
5664a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
56721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
5684a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
5694a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5704a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
5714a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
5724a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
5734a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
574fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
57521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
576fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
577fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
578fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
579fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
580fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
581fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
582ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
58321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
584ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
585ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
586ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
587ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
588ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
589ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
590ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
591ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
592ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
59321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
594ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
595ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
596ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
597ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
598ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
599ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
60070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
60121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
60270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
60370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
60470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
60570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
60670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
60770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
608f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
60921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
611f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
61721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
619f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
6246bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
62521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
6266bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
6276bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6286bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
6296bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
6306bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
6316bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
6326b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
63321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
6346b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
6356b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6366b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
6376b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
6386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
6396b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
640c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
64121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
642c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
643c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
644c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
645c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
646c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
647c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
64821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isReg() const { return Kind == k_Register; }
64921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegList() const { return Kind == k_RegisterList; }
65021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isDPRRegList() const { return Kind == k_DPRRegisterList; }
65121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isSPRRegList() const { return Kind == k_SPRRegisterList; }
65221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isToken() const { return Kind == k_Token; }
65321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
65421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMemory() const { return Kind == k_Memory; }
65521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isShifterImm() const { return Kind == k_ShifterImmediate; }
65621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedReg() const { return Kind == k_ShiftedRegister; }
65721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRegShiftedImm() const { return Kind == k_ShiftedImmediate; }
65821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isRotImm() const { return Kind == k_RotateImmediate; }
65921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isBitfield() const { return Kind == k_BitfieldDescriptor; }
66021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isPostIdxRegShifted() const { return Kind == k_PostIndexRegister; }
661f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
66221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    return Kind == k_PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
663f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
6647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemNoOffset() const {
665f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
666ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
6677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
6687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0;
669ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
6707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
671f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
672ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
6737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
6747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return true;
6757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
6767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
6797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
680039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
68121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
682039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
683039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
684039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
685039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
686039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
687039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
688039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
6892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
690f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
6912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
6922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
6932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.ShiftType != ARM_AM::no_shift) return false;
6942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
6952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.OffsetRegNum) return true;
6962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetImm) return true;
6982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
7002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
7012fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
70221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate && Kind != k_PostIndexRegister)
7032fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
70421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister)
7052fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
7062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
7072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
7092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
710251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
711251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
7122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
7137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
714f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory())
715ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
7167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
7177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return false;
7187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
7197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
7207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
7210da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
7220da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson           Val == INT32_MIN;
7237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
7247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
725f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative ||
7267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
7277f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
7287f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
7297f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
7307f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
731f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative ||
7327f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach        Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm != 1)
7337f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
7347f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
7357f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
7367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
737f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || !Mem.OffsetRegNum)
738ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
739ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
740ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
741ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
742f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative)
743ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
744ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
745ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    if (Mem.ShiftType == ARM_AM::no_shift)
746ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
747ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    if (Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm > 3)
748ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
749ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
750ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
7517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
7527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
7537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
754f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || !Mem.OffsetRegNum || Mem.isNegative ||
7557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
75687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
75760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    return isARMLowRegister(Mem.BaseRegNum) &&
75860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum));
75960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
76060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
761f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0 ||
76260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
76360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
76460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
76560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (!Mem.OffsetImm) return true;
76660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
767ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
768ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
76938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
770f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0 ||
77138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
77238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
77338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
77438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (!Mem.OffsetImm) return true;
77538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
77638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
77738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
77848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
779f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0 ||
78048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
78148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
78248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
78348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (!Mem.OffsetImm) return true;
78448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
78548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
78648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
787ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
788f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP)
789ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
790ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
791ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (!Mem.OffsetImm) return true;
792ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
793ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
794505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
795a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
796f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
797a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
798a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
799a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!Mem.OffsetImm) return true;
800a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
801a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
802a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
803b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
804f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
805b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
806b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
807b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    if (!Mem.OffsetImm) return true;
808b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
809b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
810b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
8117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
812f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
813f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
8147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
8167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
8174d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
818f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
819f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
820f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
821f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
822f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
823f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    if (!Mem.OffsetImm) return true;
824f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
825f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
826f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
827a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
828f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
829a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
830a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
831a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (!Mem.OffsetImm) return true;
832a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
833a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return Val > -256 && Val < 0;
834a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
835a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
836a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
837a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
838a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // and we reject it.
83921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
840a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return true;
841a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
842f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
843a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
844a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
845a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (!Mem.OffsetImm) return true;
846a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
847a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
848a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
8497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
85009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
85109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
85209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
85321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate && !isa<MCConstantExpr>(getImm()))
85409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
85509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
856f6c35c59f515505fa2e9b74b3d0f4ab06f8266d8Jim Grosbach    if (!isMemory() || Mem.OffsetRegNum != 0)
857ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
8610da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
8637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
86421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind != k_Immediate)
8657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
8667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
867ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
8687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
86963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
870ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
8717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
87221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isMSRMask() const { return Kind == k_MSRMask; }
87321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  bool isProcIFlags() const { return Kind == k_ProcIFlags; }
8743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
875460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex8() const {
876460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
877460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 8;
878460a90540b045c102012da2492999557e6840526Jim Grosbach  }
879460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex16() const {
880460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
881460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 4;
882460a90540b045c102012da2492999557e6840526Jim Grosbach  }
883460a90540b045c102012da2492999557e6840526Jim Grosbach  bool isVectorIndex32() const {
884460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Kind != k_VectorIndex) return false;
885460a90540b045c102012da2492999557e6840526Jim Grosbach    return VectorIndex.Val < 2;
886460a90540b045c102012da2492999557e6840526Jim Grosbach  }
887460a90540b045c102012da2492999557e6840526Jim Grosbach
888460a90540b045c102012da2492999557e6840526Jim Grosbach
889460a90540b045c102012da2492999557e6840526Jim Grosbach
8903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
89114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
89214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
89314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
89414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
8953483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
8963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
8973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
8983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
8993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9008462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
901345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
9028462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
90304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
90404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
9058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
9068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
907fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
908fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
909fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
910fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
911fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
91289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
91389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
91489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
91589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
91689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
91789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
91889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
91989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
92089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
92189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
922fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
923fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
924fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
925fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
926fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
927d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
928d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
929d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
930d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
931d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
932a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
933a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
934a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
935a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
936a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
937af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
938e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
939af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
940af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
941af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
942e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
943af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
944e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
945e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
946af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
947152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
948af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
949af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
95092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
951af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
95292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
95392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
954580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
9550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
956580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
957580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
9580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
9590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
96087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
9617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
9625fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
9635fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
9647729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
9657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
96687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
96787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
9680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
9690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
9700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
9710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
9730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
9740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
9750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
9777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
9797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
9807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
9817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
982293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
983293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
984293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
985293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
986293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
987293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
988293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
989293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
990293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
991293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
992293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
9933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
9946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
9966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
9976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
9989d39036f62674606565217a10db28171b9594bc7Jim Grosbach  void addFPImmOperands(MCInst &Inst, unsigned N) const {
9999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
10009d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getFPImm()));
10019d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
10029d39036f62674606565217a10db28171b9594bc7Jim Grosbach
1003a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
1004a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1005a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
1006a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
1007a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1008a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
1009a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1010a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
101172f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
101272f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
101372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
101472f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
101572f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
101672f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
101772f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
101872f39f8436848885176943b0ba985a7171145423Jim Grosbach
101972f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
102072f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
102172f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
102272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
102372f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
102472f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
102572f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
102672f39f8436848885176943b0ba985a7171145423Jim Grosbach
10276b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
10286b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
10296b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
10306b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
10316b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
103283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
103383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
103483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
103583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
103683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
103783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
10387c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
10397c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
10407c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
10417c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
10427c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
104383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
104483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
104583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
104683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
1047f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1048f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1049f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
1050f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
1051f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1052f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
1053f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1054f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
10554a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
10564a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
10574a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
10584a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
10594a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10604a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
10614a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
10624a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
1063fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1064fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1065fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
1066fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
1067fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
1068ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
1069ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1070ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
1071ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
1072ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach
1073ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
1074ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1075ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    addExpr(Inst, getImm());
107670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
107770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach
107870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
107970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
108070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
108170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
108270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
108370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
108470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1085ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1086ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1087f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
1088f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1089f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
1090f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1091f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1092f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1093f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1094f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1095f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1096f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1097f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1098f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1099f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1100f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
11016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
11026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
11036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
11046bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
11056bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
11066b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
11073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
11083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
11093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
111016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1111c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
1112c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1113c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
1114c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1115c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1116706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1117706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1118706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1119706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1120706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
11217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
11227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1124505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1125505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
11267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
11277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
11287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
11297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetRegNum) {
11307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
11317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
11327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
11337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
11347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
11357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
11367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
11377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
11387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
1139dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach                              Mem.ShiftImm, Mem.ShiftType);
1140ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
11417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
11437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1144ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1145ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1146039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1147039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1148039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1149039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1150039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1151039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1152039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1153039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1154039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1155039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1156039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1157039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1158039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1159039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
11602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
11612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
11622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
11632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetRegNum) {
11642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
11652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
11662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
11672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
11682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
11692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
11702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
11712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
11722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
11732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
11742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
11762fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
11772fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
11782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
11792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
11802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
118121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_PostIndexRegister) {
11822fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
11832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
11842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
11852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1186251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
11872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
11882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
11892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
11902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
11912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
11922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
11932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
11942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
11952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1196251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
11972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
11982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
11992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
12002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
12017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
12027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
12037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
12047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
12057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
12067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
12077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
12087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
12097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
12107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
12127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
12137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1214a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1215a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1216a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
1217a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1218a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1219a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1220a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1221b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1222b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1223b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1224b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
1225b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1226b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1227b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1228b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
12297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
12307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
12317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
12327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1234ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1235ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1236f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1237f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1238f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1239f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1240a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1241f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1242a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1243a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1244a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1245a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1246a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
124721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
1248a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1249a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1250a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1251a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1252a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1253a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1254a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
1255a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1256a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1257a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1258a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
12597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
12607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
126109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
126221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    if (Kind == k_Immediate) {
126309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
126409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
126509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
126609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
126709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
126809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
12697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
12707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
12727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
127392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
12747f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
12757f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
12767f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12777f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
12787f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
12797f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
12807f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
12817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
12827f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12837f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
12847f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
12857f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
12867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
12877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
12887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
12890d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                     Mem.ShiftImm, Mem.ShiftType);
12907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
12927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
12937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1294d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1295ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1296ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1297ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1298ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
1299ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mem.ShiftImm));
1300ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1301ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
13027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
13037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
13047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
13057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
130614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
13073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
130860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
130960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
131060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
131160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
131260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
131348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
131448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
131538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
131638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
131738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0;
131838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
131938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
132038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
132138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
132248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
132348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
132448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0;
132548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
132648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
132760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
132860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1329ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1330ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1331ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
1332ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1333ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1334ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1335ecd858968384be029574d845eb098d357049e02eJim Grosbach
13367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
13377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
13387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
13397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
13407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
13417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
134263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
13437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
13447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1345f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1346ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
13477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
13487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
13497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1350f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1351f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1352f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1353f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1354f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1355f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1356f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1357f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1358f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1359f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1360f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1361f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1362ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1363ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1364584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1365584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1366584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1367584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1368584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1370a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1371a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1372a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1373a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1374460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
1375460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1376460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1377460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1378460a90540b045c102012da2492999557e6840526Jim Grosbach
1379460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex16Operands(MCInst &Inst, unsigned N) const {
1380460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1381460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1382460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1383460a90540b045c102012da2492999557e6840526Jim Grosbach
1384460a90540b045c102012da2492999557e6840526Jim Grosbach  void addVectorIndex32Operands(MCInst &Inst, unsigned N) const {
1385460a90540b045c102012da2492999557e6840526Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1386460a90540b045c102012da2492999557e6840526Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
1387460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1388460a90540b045c102012da2492999557e6840526Jim Grosbach
1389b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1390b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
139189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
139221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ITCondMask);
139389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
139489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
139589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
139689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
139789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
139889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
13993a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
140021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CondCode);
1401345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1402345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1403345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
14043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1405345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1406345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1407fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
140821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocNum);
1409fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1410fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1411fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1412fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1413fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1414fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1415fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
141621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CoprocReg);
1417fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1418fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1419fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1420fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1421fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1422fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1423d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
142421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_CCOut);
1425d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1426d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1427d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1428d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1429d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1430d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
14313a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
143221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Token);
1433762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1434762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1435762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1436762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
14373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1438a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1439a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
144121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Register);
1442762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1443762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1444762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
14453a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1446a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1447a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1448e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1449e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1450e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1451e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1452e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
145321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedRegister);
1454af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1455af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1456af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1457af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1458e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1459e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1460e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1461e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1462e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
146392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
146492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
146592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
146692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
146721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShiftedImmediate);
1468af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1469af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1470af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
147192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
147292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
147392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
147492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
147592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1476580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
14770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
147821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ShifterImmediate);
1479580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1480580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
14810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
14820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
14830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
14840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
14867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
148721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_RotateImmediate);
14887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
14897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
14907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
14917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
14927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1494293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1495293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
149621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_BitfieldDescriptor);
1497293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1498293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1499293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1500293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1501293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1502293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1503293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
15047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
15055fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1506cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
150721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    KindTy Kind = k_RegisterList;
15080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1509d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
151021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_DPRRegisterList;
1511d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
1512275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
151321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach      Kind = k_SPRRegisterList;
15140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
15150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
15165fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
15177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
151824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1519cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1520cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1521cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
15228d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
15238d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
15248d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
1525460a90540b045c102012da2492999557e6840526Jim Grosbach  static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
1526460a90540b045c102012da2492999557e6840526Jim Grosbach                                       MCContext &Ctx) {
1527460a90540b045c102012da2492999557e6840526Jim Grosbach    ARMOperand *Op = new ARMOperand(k_VectorIndex);
1528460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->VectorIndex.Val = Idx;
1529460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->StartLoc = S;
1530460a90540b045c102012da2492999557e6840526Jim Grosbach    Op->EndLoc = E;
1531460a90540b045c102012da2492999557e6840526Jim Grosbach    return Op;
1532460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1533460a90540b045c102012da2492999557e6840526Jim Grosbach
15343a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
153521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Immediate);
1536762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1537762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1538762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
15393a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1540cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1541cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
15429d39036f62674606565217a10db28171b9594bc7Jim Grosbach  static ARMOperand *CreateFPImm(unsigned Val, SMLoc S, MCContext &Ctx) {
154321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_FPImmediate);
15449d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->FPImm.Val = Val;
15459d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->StartLoc = S;
15469d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Op->EndLoc = S;
15479d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return Op;
15489d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
15499d39036f62674606565217a10db28171b9594bc7Jim Grosbach
15507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
15517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
15527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
15537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
15540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
15557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
15563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
155721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_Memory);
1558762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
15597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetImm = OffsetImm;
15607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetRegNum = OffsetRegNum;
1561762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
15620d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Op->Mem.ShiftImm = ShiftImm;
15637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.isNegative = isNegative;
15647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
15657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
15667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
15677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
156816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1569f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1570f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
1571f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
15727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
157321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_PostIndexRegister);
15747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
1575f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
1576f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
1577f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
1578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1579762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
15803a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1582706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1583706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
158421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MemBarrierOpt);
1585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1586706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1587706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1588706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1589706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1590a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1591a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
159221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_ProcIFlags);
1593a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1594a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1595a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1596a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1597a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
160021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach    ARMOperand *Op = new ARMOperand(k_MSRMask);
1601584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1605584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1608a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1609a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1610b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1611fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
161221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_FPImmediate:
16139d39036f62674606565217a10db28171b9594bc7Jim Grosbach    OS << "<fpimm " << getFPImm() << "(" << ARM_AM::getFPImmFloat(getFPImm())
16149d39036f62674606565217a10db28171b9594bc7Jim Grosbach       << ") >";
16159d39036f62674606565217a10db28171b9594bc7Jim Grosbach    break;
161621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CondCode:
16176a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1618fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
161921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CCOut:
1620d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1621d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
162221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ITCondMask: {
162389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)",
162489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)",
162589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(tee)", "(eee)" };
162689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
162789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
162889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
162989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
163021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocNum:
1631fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1632fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
163321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_CoprocReg:
1634fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1635fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
163621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MSRMask:
1637584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1638584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
163921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Immediate:
1640fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1641fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
164221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_MemBarrierOpt:
1643706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1644706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
164521ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Memory:
16466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
16477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << " base:" << Mem.BaseRegNum;
16486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1649fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
165021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_PostIndexRegister:
1651f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
1652f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
1653f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
1654f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
1655f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
1656f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
16577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
165821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ProcIFlags: {
1659a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1660a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1661a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1662a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1663a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1664a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1665a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1666a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
166721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Register:
166850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1669fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
167021ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShifterImmediate:
1671580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1672580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
1673e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
167421ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedRegister:
167592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1676af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedReg.SrcReg
1677af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1678af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << RegShiftedReg.ShiftReg << ", "
1679af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1680e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
16810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
168221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_ShiftedImmediate:
168392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
1684af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedImm.SrcReg
1685af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1686af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
168792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
168892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
168921ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RotateImmediate:
16907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
16917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
169221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_BitfieldDescriptor:
1693293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1694293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
1695293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
169621ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_RegisterList:
169721ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_DPRRegisterList:
169821ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_SPRRegisterList: {
16998d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
17008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
17015fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
17025fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
17037729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
17047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
17057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
17068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
17078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
17088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
17098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
17108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
171121ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  case k_Token:
1712fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1713fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1714460a90540b045c102012da2492999557e6840526Jim Grosbach  case k_VectorIndex:
1715460a90540b045c102012da2492999557e6840526Jim Grosbach    OS << "<vectorindex " << getVectorIndex() << ">";
1716460a90540b045c102012da2492999557e6840526Jim Grosbach    break;
1717fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1718fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
17193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
17203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
17213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
17223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
17233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
17243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
17253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
17263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
172769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
172869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
17291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
1730bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1731bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1732bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1733bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
17349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1735e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1736e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
17373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
17381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
173918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
17407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
1741d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1742a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
17440c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
17450c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
17460c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
17470c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
17480c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
17490c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
17500c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
17510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
17520c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
17530c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
17540c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
17550c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
175669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1757b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1758460a90540b045c102012da2492999557e6840526Jim Grosbach
1759460a90540b045c102012da2492999557e6840526Jim Grosbach#if 0
1760460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
1761460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
1762460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
1763460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
1764460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
1765460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
1766460a90540b045c102012da2492999557e6840526Jim Grosbach
1767460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
1768460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc ExprLoc = Parser.getTok().getLoc();
1769460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
1770460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
1771460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
1772460a90540b045c102012da2492999557e6840526Jim Grosbach    if (!MCE) {
1773460a90540b045c102012da2492999557e6840526Jim Grosbach      TokError("immediate value expected for vector index");
1774460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
1775460a90540b045c102012da2492999557e6840526Jim Grosbach    }
1776460a90540b045c102012da2492999557e6840526Jim Grosbach
1777460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
1778460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
1779460a90540b045c102012da2492999557e6840526Jim Grosbach      Error(E, "']' expected");
1780460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
1781460a90540b045c102012da2492999557e6840526Jim Grosbach    }
1782460a90540b045c102012da2492999557e6840526Jim Grosbach
1783460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
1784460a90540b045c102012da2492999557e6840526Jim Grosbach
1785460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
1786460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
1787460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
1788460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1789460a90540b045c102012da2492999557e6840526Jim Grosbach#endif
1790460a90540b045c102012da2492999557e6840526Jim Grosbach
1791e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1792e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1793d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
179419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
179519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
179619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
179719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
179819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
17990d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
18000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
18010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
18020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
18030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
18040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
18050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
18060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
18070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
18080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
18090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
18100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
18110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
18120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
18130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
18140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
18150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
181619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
18170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1818e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1819e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1820e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1821e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1822e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1823eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1824e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1825e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1826e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1827e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1828e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1829e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1830e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1831e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1832e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1833e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1834e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1835e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1836e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1837e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1838e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1839e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
184019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
184119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
184219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
184319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1844e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1845e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
184619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
184719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
184819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
184919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1850e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1851e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1852e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1853e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1854e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1855e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1856e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
185719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
185819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1859e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1860e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
18611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
1862e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
186319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
186419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
186519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
186619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
186719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
186819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1869e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
187019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
187119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1872e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1873e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
187492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
187592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1876af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
18770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
187892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
187992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
188092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
18810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
188219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
18830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
18840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
18850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
188650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
188750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
188850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1889e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1890e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1891e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
189250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
18931355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1894e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
18951355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
1896e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
189750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1898d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
189950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1900a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1901e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1902e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
190350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
190450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1905e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
1906460a90540b045c102012da2492999557e6840526Jim Grosbach    return false;
1907460a90540b045c102012da2492999557e6840526Jim Grosbach  }
1908460a90540b045c102012da2492999557e6840526Jim Grosbach
1909460a90540b045c102012da2492999557e6840526Jim Grosbach  // Also check for an index operand. This is only legal for vector registers,
1910460a90540b045c102012da2492999557e6840526Jim Grosbach  // but that'll get caught OK in operand matching, so we don't need to
1911460a90540b045c102012da2492999557e6840526Jim Grosbach  // explicitly filter everything else out here.
1912460a90540b045c102012da2492999557e6840526Jim Grosbach  if (Parser.getTok().is(AsmToken::LBrac)) {
1913460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc SIdx = Parser.getTok().getLoc();
1914460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat left bracket token.
1915460a90540b045c102012da2492999557e6840526Jim Grosbach
1916460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCExpr *ImmVal;
1917460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc ExprLoc = Parser.getTok().getLoc();
1918460a90540b045c102012da2492999557e6840526Jim Grosbach    if (getParser().ParseExpression(ImmVal))
1919460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
1920460a90540b045c102012da2492999557e6840526Jim Grosbach    const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
1921460a90540b045c102012da2492999557e6840526Jim Grosbach    if (!MCE) {
1922460a90540b045c102012da2492999557e6840526Jim Grosbach      TokError("immediate value expected for vector index");
1923460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
1924460a90540b045c102012da2492999557e6840526Jim Grosbach    }
1925460a90540b045c102012da2492999557e6840526Jim Grosbach
1926460a90540b045c102012da2492999557e6840526Jim Grosbach    SMLoc E = Parser.getTok().getLoc();
1927460a90540b045c102012da2492999557e6840526Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac)) {
1928460a90540b045c102012da2492999557e6840526Jim Grosbach      Error(E, "']' expected");
1929460a90540b045c102012da2492999557e6840526Jim Grosbach      return MatchOperand_ParseFail;
1930460a90540b045c102012da2492999557e6840526Jim Grosbach    }
1931460a90540b045c102012da2492999557e6840526Jim Grosbach
1932460a90540b045c102012da2492999557e6840526Jim Grosbach    Parser.Lex(); // Eat right bracket token.
1933460a90540b045c102012da2492999557e6840526Jim Grosbach
1934460a90540b045c102012da2492999557e6840526Jim Grosbach    Operands.push_back(ARMOperand::CreateVectorIndex(MCE->getValue(),
1935460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     SIdx, E,
1936460a90540b045c102012da2492999557e6840526Jim Grosbach                                                     getContext()));
193799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
193899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
193950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1940a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1941a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1942fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1943fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1944fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1945fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1946e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1947e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1948e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1949e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1950e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1951fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1952e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1953e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1954e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1955e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1956e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1957e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1958e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1959e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1960e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1961e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1962e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1963e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1964e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1965e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1966e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1967e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1968fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1969e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1970e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1971e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1972e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1973e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1974e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1975e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1976e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1977e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1978e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1979e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1980e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1981e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1982e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1983e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1984e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
198589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
198689df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
198789df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
198889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
198989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
199089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
199189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
199289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
199389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
199489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
199589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
199689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
199789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
199889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
199989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
200089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
200189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
200289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
200389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
200489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
200589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
200689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
200789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
200889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
200989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
201089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
201189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
201289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
201389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
201489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
201589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
201689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
201789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
201889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
201989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
202043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
2021fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2022fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2023f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
202443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2025e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
2026e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
2027e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2028e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2029fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
2030e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
2031f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2032e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2033e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
2034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
2035f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2036fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
2037fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
203843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
2039fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
2040fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
2041f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
204243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2043fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2044fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2045fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2046fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2047fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
2048fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
2049f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2050fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2051fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2052fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
2053f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2054e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
2055e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2056d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
2057d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
2058d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
2059d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
2060d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
2061d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
2062d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
2063d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2064d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
2065d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
2066d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
2067d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
2068d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
2069d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
2070d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
2071d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
2072d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
2073d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
2074d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
2075d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2076d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
2077d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2078d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
207950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
20801355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
208118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
2082a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
2083e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
2084d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
2085d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
208616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2087d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
2088d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
2089d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
2090d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
2091d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
2092d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2093d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  MCRegisterClass *RC;
2094d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
2095d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
2096d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
2097d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
2098d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
2099d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
2100d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
2101d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
2102e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
2103d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
2104d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // space for that many.
2105d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
2106d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Store the first register.
2107d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2108d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2109d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
2110d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
2111d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
2112d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
2113d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
2114d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
2115d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      Parser.Lex(); // Eat the comma.
2116d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
2117d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
2118d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
2119d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
2120d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
2121d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
2122d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
2123d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
2124d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
2125d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
2126d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
2127d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
2128d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
2129d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
2130d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2131d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
2132d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
2133d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
2134d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2135d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
2136d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
2137d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
2138d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
2139d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
2140d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
2141d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
2142d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
21432d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
2144d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
2145d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
2146d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
2147d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
2148d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg))
2149d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
2150d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
2151d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
2152d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
2153d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
2154d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
2155d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
2156d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2157d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2158d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2159d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2160d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2161d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2162d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2163e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
216450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
216550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2166d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2167d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
216843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
2169f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
217043904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2171706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2172706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2173706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2174706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
2175706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2176706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
2177706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
2178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
2179032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
2180706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
2181032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
2182706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
2183706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
2184032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
2185706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
2186032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
2187706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
2188706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
2189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
2190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
2192f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2193706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2194706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2195706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
2196f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2197706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
2198706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
219943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
2200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
220143904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2202a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2205a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
2206a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
22072dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // An iflags string of "none" is interpreted to mean that none of the AIF
22082dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  // bits are set.  Not a terribly useful instruction, but a valid encoding.
2209a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
22102dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson  if (IFlagsStr != "none") {
22112dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
22122dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
22132dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("a", ARM_PROC::A)
22142dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("i", ARM_PROC::I)
22152dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Case("f", ARM_PROC::F)
22162dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        .Default(~0U);
22172dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
22182dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // If some specific iflag is already set, it means that some letter is
22192dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      // present more than once, this is not acceptable.
22202dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      if (Flag == ~0U || (IFlags & Flag))
22212dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson        return MatchOperand_NoMatch;
22222dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson
22232dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson      IFlags |= Flag;
22242dbb46a0a09d4a16a6752cfcbe1d55d51e7d2a31Owen Anderson    }
2225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2227a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2228a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
2229a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
2230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
2231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
223243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
2233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
223443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2235584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
2239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2240acad68da50581de905a994ed3c6b9c197bcea687James Molloy  if (isMClass()) {
2241acad68da50581de905a994ed3c6b9c197bcea687James Molloy    // See ARMv6-M 10.1.1
2242acad68da50581de905a994ed3c6b9c197bcea687James Molloy    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
2243acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("apsr", 0)
2244acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iapsr", 1)
2245acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("eapsr", 2)
2246acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("xpsr", 3)
2247acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("ipsr", 5)
2248acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("epsr", 6)
2249acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("iepsr", 7)
2250acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("msp", 8)
2251acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("psp", 9)
2252acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("primask", 16)
2253acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri", 17)
2254acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("basepri_max", 18)
2255acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("faultmask", 19)
2256acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Case("control", 20)
2257acad68da50581de905a994ed3c6b9c197bcea687James Molloy      .Default(~0U);
2258acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2259acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (FlagsVal == ~0U)
2260acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
2261acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2262acad68da50581de905a994ed3c6b9c197bcea687James Molloy    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
2263acad68da50581de905a994ed3c6b9c197bcea687James Molloy      // basepri, basepri_max and faultmask only valid for V7m.
2264acad68da50581de905a994ed3c6b9c197bcea687James Molloy      return MatchOperand_NoMatch;
2265acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2266acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Parser.Lex(); // Eat identifier token.
2267acad68da50581de905a994ed3c6b9c197bcea687James Molloy    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2268acad68da50581de905a994ed3c6b9c197bcea687James Molloy    return MatchOperand_Success;
2269acad68da50581de905a994ed3c6b9c197bcea687James Molloy  }
2270acad68da50581de905a994ed3c6b9c197bcea687James Molloy
2271584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
2272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
2273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
2274b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
2275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
2276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
2277584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2278584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
2279584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
2280584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2281584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
2282584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2283584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
2284584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
2285b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
2286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
2287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
2288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
2289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
22904b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
2291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
2292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
2293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
2294bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
22954b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
2296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
229756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
229856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
2299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
2300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
2301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
2302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
2303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
2304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
2305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
2306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
2308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
2309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
2310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
2311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
2312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
2313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
2314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
2315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
2317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
2318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
2319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
2322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
2323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
2327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
2328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2329f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2330f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
2331f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
2332f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2333f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2334f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2335f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2336f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2337f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
2338f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
2339f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
2340f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
2341f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2342f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2343f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2344f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
2345f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2346f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
2347f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2348f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2349f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2350f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2351f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
2352f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2353f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
2354f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
2355f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2356f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
2357f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2358f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2359f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2360f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
2361f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
2362f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2363f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2364f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
2365f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
2366f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
2367f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2368f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2369f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2370f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
2371f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2372f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
2373f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
2374f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2375c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2376c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2377c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2378c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
2379c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2380c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2381c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2382c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2383c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
2384c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
2385c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
2386c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
2387c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
2388c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2389c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
2390c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2391c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2392c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2393c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
2394c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
2395c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
2396c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
2397c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
2398c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2399580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
2400580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
2401580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
2402580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
2403580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
2404580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2405580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2406580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
2407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
2408580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2409580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2410580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2411580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2412580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
2413580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
2414580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
2415580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
2416580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
2417580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
2418580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
2419580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2420580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2421580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2422580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
2423580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2424580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
2425580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2426580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2427580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2428580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2429580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
2430580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2431580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
2432580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2433580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2434580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
2435580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2436580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
2439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
2440580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2441580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2442580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2443580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
2444580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
2445580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2446580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
2447580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
2448580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2449580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
24500afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
24510afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
24520afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
24530afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
24540afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
2455580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
2456580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
2457580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2458580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
2459580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
2460580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2461580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
2462580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2463580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2464580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
2465580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
2466580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2467580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
2468580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
2469580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
24707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
24717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
24727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
24737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
24747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
24767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
2477326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2478326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
24797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
2480326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
2481326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
24827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
24837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
24847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
24857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
24867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
24877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
24887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
24897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
24907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
24917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
24927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
24937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
24947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
24957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
24967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
24977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
24987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
24997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
25007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
25017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
25027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
25037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
25047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
25057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
25067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
25077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
25087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
25097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
25107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
25117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
25127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
25137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
25147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
25157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
25167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
25177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2518293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2519293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2520293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
2521293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
2522293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2523293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2524293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2525293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2526293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2527293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2528293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
2529293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2530293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
2531293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2532293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2533293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2534293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
2535293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2536293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
2537293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2538293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2539293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2540293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
2541293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
2542293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
2543293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
2544293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2545293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2546293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2547293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2548293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
2549293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
2550293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
2551293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2552293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2553293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2554293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2555293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2556293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2557293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2558293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2559293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2560293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
2561293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
2562293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2563293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2564293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2565293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
2566293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2567293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
2568293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2569293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2570293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2571293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
2572293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
2573293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
2574293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
2575293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2576293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2577293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2578293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2579293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
2580293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2581293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
2582293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
2583293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
25847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
25857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
25867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2587f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
2588f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
2589f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
25907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
25917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
25927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
25937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
25947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
25957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
25967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
259716578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
26017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
26027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
26037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
260416578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
26057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
26067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
26077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
26087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
26097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
26107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
26117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
26127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
26137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
26147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
26157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
26167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2617f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
2618f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
26190d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
26200d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
26210d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
26220d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
26230d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
2624f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
2625f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
2626f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
26277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
26287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
26297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
26307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2631251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2632251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2633251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2634251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
2635251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
2636251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
2637251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
2638251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
2639251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
2640251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2641251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
2642251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
2643251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
2644251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
2645251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
2646251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2647251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
2648251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
2649251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
2650251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
2651251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
2652251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2653251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
2654251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
2655251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2656251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
2657251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
2658251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
2659251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2660251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
2661251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
2662251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
2663251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
2664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
2665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
2666251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2667251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
2668251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
2669251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2670251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
2671251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2672251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2673251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2674251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
2675251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
2676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
2677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
2678251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
2679251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2680251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
2681251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
2682251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
2683251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2684251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2685251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
2686251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
2687251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
2688251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
2689251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
2690251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
2691251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
2692251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2693251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2694251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2695251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
2696251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
2697251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2698251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
2699251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
2700251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2701a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
2702a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2703a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2704a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
2705a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
2706a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2707a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
2708a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2709a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
2710a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
2711a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
2712a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
2713a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
2714a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
2715a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2716a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
2717a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
2718a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
2719a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
2720a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2721a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2722a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
2723a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
2724a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2725a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
2726a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
2727a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
2728a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2729a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
2730a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
2731a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
2732a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
2733a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2734a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
2735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
2736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
2737eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
2738eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2739eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2740eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
2741eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
2742eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2743eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2744eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
2745eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
2746eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2747eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
2748eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
2749eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2750eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
2751eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
2752eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
2753ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
2754ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2755ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2756ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
2757ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
2758ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2759ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
2760ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2761ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2762ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
2763ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2764ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
2765ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
2766ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
27671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2770ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
27711355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2772ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2773ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2774ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
2775ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2776ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2777ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
27787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2779ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2780ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2781ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2782ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
27839ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
27849ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
27859ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
27869ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
27879ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
27889ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
27899ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
27909ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
27919ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
27929ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
27939ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
27949ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
27959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
27969ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
27979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
27989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
27999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
2800548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
2801548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2802548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2803548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
2804548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
2805548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2806548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
2807548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2808548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2809548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
2810548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2811548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
2812548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
2813548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
28141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2815ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2816ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2817ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
28181355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2819ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2820ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2822548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2823548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2824548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
28257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
28267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
28277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
28287b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
28297b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
28307b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
28317b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
28327b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
28337b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
28347b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
28357b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
28367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
28377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
28387b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
28397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
28407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
28417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
28427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
28437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
28447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
28457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
28467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
28477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
28487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2849ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
28507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
28517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
28527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
28537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
28547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
28557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
28567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2857ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2858ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2859ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2860ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
28617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
2862ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2863ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2864ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
28657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
28667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
28677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2868aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2869ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2870ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
28717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
28727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
28737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
28747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
28757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
28767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
28777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
28787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
2879aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
28807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
28817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
28827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
28837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
28847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
28857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
28867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
28877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
28887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
28897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
28907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
28917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
28927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
28937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
28947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2895ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2896ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2897ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2898ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
2900ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2901ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2902ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
29037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
29047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2905ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2906ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2908ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
29097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
29107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
29117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
29127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
29137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2914ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2915ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2916ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2917ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
29182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
29192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
29202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
29212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
29222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
29232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
29242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
29252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
29262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
29272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
29282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
29292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
29302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
29312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
29322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
29332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
29342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
29352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
293614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
293714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
293814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
293914605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
294014605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
294114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
294214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
294314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
294414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
294514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
294614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
294714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
294814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
294914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
295014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
295114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
295214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
295314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
2954623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
2955623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2956623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2957623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
2958623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
2959623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2960623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2961623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
2962623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2963623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
2964623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2965623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
2966623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
2967623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
296888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
296988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
297088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
297188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
297288ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
297388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
297488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
297588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
297688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
29777a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
29787a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
29797a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
29807a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
298188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
29827a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
298388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
298488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
298588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
298688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
298788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
29887a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // If we have a three-operand form, use that, else the second source operand
29897a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // is just the destination operand again.
29907a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  if (Operands.size() == 6)
29917a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
29927a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  else
29937a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    Inst.addOperand(Inst.getOperand(0));
299488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
299588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
299688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
299788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
2998623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
2999e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
30009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
300150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
30027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3003762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
300418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
3005a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
3006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
3007b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
3008a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
300918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
30101355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
30117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
30127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
3013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
30140571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
30150571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
30160571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
30177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
30180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
30197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
3020762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
3021b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
3022a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
30237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
30247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             0, false, S, E));
302503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
3026fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
3027fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
3028fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
3029fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3030fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
3031fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
3032fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
30337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
30347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
303550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
30367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
30377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
303850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
30397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If we have a '#' it's an immediate offset, else assume it's a register
30407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset.
30417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
30427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '#'.
30437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
304450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
30450da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
30467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
30477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
30487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
304905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
30507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
30517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
30527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
30537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
30547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
30557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
30567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
30570da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
30580da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
30590da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
30600da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
30610da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
30627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
30637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
30647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
30657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
30667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
306705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
30687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
30697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
30707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
30717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             ARM_AM::no_shift, 0, false, S,E));
3072a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
30737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
30747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
30757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
30767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
30777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
3078762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
30797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
30807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
30819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
3082d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
30837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
30847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
30857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
30867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
30877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
30887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
30897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
30907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
30917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
30929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
30937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
30947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
30957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
30967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
30977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
30987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
30997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
31000d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
31017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
31027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
31030d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
31047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
31059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
310616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
31077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
31087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
31097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
31107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
31117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
31127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
31137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
31140d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                           ShiftType, ShiftImm, isNegative,
31157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
31167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3117f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
3118f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
3119f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
3120f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
3121f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
3122f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
31239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
31249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
31259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
31269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
31277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
3128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
3129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
31307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
31317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
31327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
31337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
313418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3136a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
313738e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
3138a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
31390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
3140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
31410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
3142a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
31430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
3144a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
31450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
3146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
31470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
3148a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
31497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
3150b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
3151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
31527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
31537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
31547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
31557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
31567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
31577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
31587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (HashTok.isNot(AsmToken::Hash))
31597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
31607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
31619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
31627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
31637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
31647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
31657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
31667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
31677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
31687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
31697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
31707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
31717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
31727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
31737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
31747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
31757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
31767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
31777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
3178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
3180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
3181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
31829d39036f62674606565217a10db28171b9594bc7Jim Grosbach/// parseFPImm - A floating point immediate expression operand.
31839d39036f62674606565217a10db28171b9594bc7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
31849d39036f62674606565217a10db28171b9594bc7Jim GrosbachparseFPImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
31859d39036f62674606565217a10db28171b9594bc7Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
31869d39036f62674606565217a10db28171b9594bc7Jim Grosbach
31879d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash))
31889d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_NoMatch;
31899d39036f62674606565217a10db28171b9594bc7Jim Grosbach  Parser.Lex(); // Eat the '#'.
31909d39036f62674606565217a10db28171b9594bc7Jim Grosbach
31919d39036f62674606565217a10db28171b9594bc7Jim Grosbach  // Handle negation, as that still comes through as a separate token.
31929d39036f62674606565217a10db28171b9594bc7Jim Grosbach  bool isNegative = false;
31939d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
31949d39036f62674606565217a10db28171b9594bc7Jim Grosbach    isNegative = true;
31959d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex();
31969d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
31979d39036f62674606565217a10db28171b9594bc7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
31989d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Real)) {
31999d39036f62674606565217a10db28171b9594bc7Jim Grosbach    APFloat RealVal(APFloat::IEEEdouble, Tok.getString());
32009d39036f62674606565217a10db28171b9594bc7Jim Grosbach    uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
32019d39036f62674606565217a10db28171b9594bc7Jim Grosbach    // If we had a '-' in front, toggle the sign bit.
32029d39036f62674606565217a10db28171b9594bc7Jim Grosbach    IntVal ^= (uint64_t)isNegative << 63;
32039d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int Val = ARM_AM::getFP64Imm(APInt(64, IntVal));
32049d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
32059d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val == -1) {
32069d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("floating point value out of range");
32079d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
32089d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
32099d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
32109d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
32119d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
32129d39036f62674606565217a10db28171b9594bc7Jim Grosbach  if (Tok.is(AsmToken::Integer)) {
32139d39036f62674606565217a10db28171b9594bc7Jim Grosbach    int64_t Val = Tok.getIntVal();
32149d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Parser.Lex(); // Eat the token.
32159d39036f62674606565217a10db28171b9594bc7Jim Grosbach    if (Val > 255 || Val < 0) {
32169d39036f62674606565217a10db28171b9594bc7Jim Grosbach      TokError("encoded floating point value out of range");
32179d39036f62674606565217a10db28171b9594bc7Jim Grosbach      return MatchOperand_ParseFail;
32189d39036f62674606565217a10db28171b9594bc7Jim Grosbach    }
32199d39036f62674606565217a10db28171b9594bc7Jim Grosbach    Operands.push_back(ARMOperand::CreateFPImm(Val, S, getContext()));
32209d39036f62674606565217a10db28171b9594bc7Jim Grosbach    return MatchOperand_Success;
32219d39036f62674606565217a10db28171b9594bc7Jim Grosbach  }
32229d39036f62674606565217a10db28171b9594bc7Jim Grosbach
32239d39036f62674606565217a10db28171b9594bc7Jim Grosbach  TokError("invalid floating point immediate");
32249d39036f62674606565217a10db28171b9594bc7Jim Grosbach  return MatchOperand_ParseFail;
32259d39036f62674606565217a10db28171b9594bc7Jim Grosbach}
32269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
32279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
32281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
3229fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
3230762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
3231fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
3232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
3233fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
3234f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3235f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
3236fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
3237f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
3238f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
3239f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
3240f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
3241f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
3242fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
3243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
3244146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
3245146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
324650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
324719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
32485cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    // If this is VMRS, check for the apsr_nzcv operand.
32491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
325050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
32510d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
325219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
32530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
325419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
325519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
32565cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    if (Mnemonic == "vmrs" && Parser.getTok().getString() == "apsr_nzcv") {
32575cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      S = Parser.getTok().getLoc();
32585cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Parser.Lex();
32595cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("apsr_nzcv", S));
32605cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach      return false;
32615cd5ac6ad455880395e34ac647f1e962a83763a0Jim Grosbach    }
3262e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
3263e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
3264e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
326519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
326667b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
326767b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
3268515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
3269515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
3270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
3271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
3272515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
327350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
3274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
327550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
327650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
327750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
3278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
32791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
3280d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
32811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
328263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
3283079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
3284079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
3285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
3286b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
328763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3288515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
3289515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
329050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
329163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
329263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (!CE) {
329363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      Error(S, "constant expression expected");
329463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      return MatchOperand_ParseFail;
329563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
329663553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    int32_t Val = CE->getValue();
329763553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (isNegative && Val == 0)
329863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
3299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
330050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
330150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
330263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
33039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
33049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
33057597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
33067597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
33077597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
33081355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
33099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
33109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
33117597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
33127597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
33139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
33149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
33157597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
33167597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
33179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
33187597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
33199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
33209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
3321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
3322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
3323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
33241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
33257597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
33261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
33277597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
33289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
33299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
33308a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
33319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
33329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
33339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
33349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
33359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
33369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
33379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
33389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
33399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
33407597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
33419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
33427597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
33439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
33449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
33459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
33469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
33479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
33489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
33499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
33509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
33519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
33529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
33539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
33549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
33559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
33569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
3357352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
3358352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
3359352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
3360badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
336189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
33621355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
33635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
33645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
336589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
336689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
3367352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
3368352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
3369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
3370352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
3371badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
3372352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
3373352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
33745f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
33755f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
33765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
33775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
33785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
33795f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
33805f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
33815f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
3382352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
3383badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
33843f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
33853f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
3386ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
338771725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
338804d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
33892f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
33903f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
33913f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
33923f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
33933f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
33943f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
33953f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
33963f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
33973f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
33983f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
33993f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
34003f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
34013f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
34023f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
34033f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
34043f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
34053f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
34063f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
34073f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
34083f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
34093f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
34103f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
34113f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
34123f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
341352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
3414345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3415352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
3416352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
3417352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
341800f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
34195f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
34205f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
34215f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
3422e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
3423e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
3424352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
3425352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
3426352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
3427352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
3428a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
3429a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
3430a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
3431a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
3432a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
3433a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
3434a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
3435a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
3436a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
3437a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
3438a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
3439a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
3440a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
3441a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3442a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
344389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
344489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
344589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
344689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
344789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
344889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
3449352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
3450352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
34513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
34523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
34533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
34543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
34553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
3456fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
34571355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
3458fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
3459eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
3460eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
34613443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
3462eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
3463d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
3464eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
3465d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
34663443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
3467d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
3468d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
3469eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
3470fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
3471eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
34723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
3473eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
3474eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
3475eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
3476eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
3477ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
3478ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
34790780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
34804af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") &&
34814af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
34824af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
34834af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
34841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
34853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
3486fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
34873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
3488fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
3489fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
3490fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
349163b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
3492fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
3493fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
3494badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
3495badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3496d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
3497d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
349820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
349920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
3500d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3501d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
3502d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
3503d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
3504d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
3505d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
3506d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
3507d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
3508d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
35098adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
3510d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
3511d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
3512d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3513d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
35143912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
35153912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
35163912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
35173912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
35183912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
35193912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
35203912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
35213912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
352272f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
352320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
352420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
352520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
3526f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
3527f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
3528f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
352972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
353072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
353172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
353220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
353320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
353420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
353572f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
3536f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
3537f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
353820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
353920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
354020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
3541f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
3542f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
354320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
354420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
354520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
354620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
354720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
354820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
354920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
355020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // check against T3.
355120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
355220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
355320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
355420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
355520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
355620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
355720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
355864944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
355920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
356020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
356120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
356220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
356320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
356420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
356520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
356620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
356720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
356864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
356964944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
357064944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
357164944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
357264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
357364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
357464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
357564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
357664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
357764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
357864944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
357964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
358064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
358164944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
358264944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
358364944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
358464944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
358564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
358664944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
358764944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
358864944f48a1164c02c15ca423a53919682a89074cJim Grosbach
358964944f48a1164c02c15ca423a53919682a89074cJim Grosbach
359020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
3591f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
3592f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
3593f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
3594f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
3595f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
3596f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
3597f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
359872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
359972f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
360072f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
360172f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
36023912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
3603d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
3604d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
3605d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3606badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
3607badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
3608badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3609badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
3610badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
3611ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
3612badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3613352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
3614352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
3615a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
3616352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
361789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
36181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
361989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
3620badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
36210c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
36220c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
36230c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
36240c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
36250c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
36260c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
3627ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
3628ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
362989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
363089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
363189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
363289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
363389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
363489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
3635f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
3636f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
3637f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
3638f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
3639f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
364089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
364189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
364289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
364389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
364489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
3645f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
364689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
364789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
364889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
364989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
365089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
3651f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
365289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
365389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
3654ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
3655ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
36569717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
36573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
36583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
36593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
36603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
36613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
36623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
36633771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
36643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
36651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
36663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
366733c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
366833c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
366933c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
367033c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
3671ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
367233c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
367333c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
3674c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
3675c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
3676c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
3677c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
3678c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
3679c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
3680c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
368133c16a27370939de39679245c3dff72383c210bdJim Grosbach
36823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
3683f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
3684f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
36853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
3686f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
3687f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
36883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
36893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
36903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
3691f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
3692f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
36933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
3694f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
3695badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
3696345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3697a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
3698a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
3699a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
3700a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
3701a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
3702a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3703a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3704345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
37055747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
37065747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
37075747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
3708a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
3709a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
37104d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // For now, we're only parsing Thumb1 (for the most part), so
37114d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // just ignore ".n" qualifiers. We'll use them to restrict
37124d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // matching when we do Thumb2.
371381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
371481d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
371581d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
371681d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
37175747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
37185747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
37195747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
37205747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3721a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
37221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
3723cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
3724cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
3725cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
3726a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3727a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
3728b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
3729a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3730a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
37311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
3732cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
3733cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
3734cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
3735a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
3736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
373716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3738cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3739186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    SMLoc Loc = getLexer().getLoc();
3740cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
3741186ffac4d35c9ea669b03ac75f5e21bff1f01a7fJim Grosbach    return Error(Loc, "unexpected token in argument list");
3742cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
3743146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
374434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
3745ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3746d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
3747d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
3748d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
374920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
375020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
375120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
375220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
375320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
3754ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3755ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
3756ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
3757ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
3758ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3759cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
3760cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
3761cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
376221ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // a k_CondCode operand in the list. If we're trying to match the label
376321ff17ce1b57ad68ae01d6eee0ecc36b5dd318cfJim Grosbach  // version, remove the k_CondCode operand here.
3764cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
3765cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
3766cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3767cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
3768cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
3769cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
3770857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
3771857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
3772857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
3773857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
3774857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
3775857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
3776857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3777857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3778857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3779857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
3780857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
3781857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
378268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      delete Op;
378368259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    }
378468259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  }
378568259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  // VCMP{E} does the same thing, but with a different operand count.
378668259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach  if ((Mnemonic == "vcmp" || Mnemonic == "vcmpe") && Operands.size() == 5 &&
378768259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm()) {
378868259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[4]);
378968259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
379068259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach    if (CE && CE->getValue() == 0) {
379168259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.erase(Operands.begin() + 4);
379268259145d9ac1f8d4e2cc9fc73626254fcc5cf08Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3793857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
3794857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
3795857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
3796934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
3797934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // end. Convert it to a token here.
3798934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
3799934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3800934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3801934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3802934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    if (CE && CE->getValue() == 0) {
3803934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
3804934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3805934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
3806934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
3807934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
3808934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
38099898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
3810ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3811ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3812189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
3813aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
3814aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
3815aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
3816aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
3817aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
3818aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
3819aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
3820aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
3821aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
3822aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
3823aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
3824aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
3825aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
3826aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
3827aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
3828aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
3829aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
3830aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
383176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
383276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
383376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
383476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
383576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
383676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
383776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
383876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
383976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
384076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
384176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
3842f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
3843f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
3844f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
3845f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
3846f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[];
3847f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
3848f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) {
3849f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
3850f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
3851f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3852189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
3853189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
3854189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
3855189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3856f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3857f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
3858f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
3859b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
3860b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // being allowed in IT blocks, but not being predicable.  It just always
3861b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
3862b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
3863f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
3864f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
3865f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
3866f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
3867a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
3868f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
3869f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
3870f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
3871f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
3872f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
3873f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
3874f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
3875f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
3876f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
3877f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
3878f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
3879f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
3880f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
3881f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
3882f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
3883f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
3884f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
3885c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
3886f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
3887f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
388851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
388951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
3890f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
3891f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3892189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
38932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
38942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
38952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
3896189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
3897189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3898189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
3899189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3900189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
3901189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3902189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
3903189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3904189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
390514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
390614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
390714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
390814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
390914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
391014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
391114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
391214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
391314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
391453642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
391553642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
3916189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
3917189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3918189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3919189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
3920189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
392114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3922189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
3923189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3924189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3925fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
3926fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
3927fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
3928fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
3929fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
3930fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
3931fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
3932fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
393300c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
3934fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
393593b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
393676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
393776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
393876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
393976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
394076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
394193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
394293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
394393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
39447260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
39457260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
39467260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
3947aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
394876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
3949aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
3950aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
395193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
395276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
395393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
395493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
395576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
395676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
3957aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
39587260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
39597260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
39607260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
396193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
396293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
396393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
396476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
396576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
396676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
396776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
396876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
396976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
397076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
39716dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
3972aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3973aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
3974aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3975aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
39766dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
39776dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
39786dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
3979aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3980aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
3981aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3982aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
39836dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
39846dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
39851e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
39861e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
39878213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
39881e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
39891e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
39901e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
39911e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
3992189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3993189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3994189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
3995189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
3996189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3997f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser::
3998f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
3999f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
4000f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
4001f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
4002f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
4003f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
4004f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
4005f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
4006f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
4007f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
4008f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
4009f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
4010f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
4011f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
4012f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
4013f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
4014f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
4015f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
4016f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
4017f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
4018f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
4019f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
4020f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
4021f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
4022f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
4023f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
4024f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
4025f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
4026f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
4027f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
4028f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
4029f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
4030f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
4031f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
4032f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
4033f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
403489e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
40350f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
40360f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
40370f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
40380f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
40390f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
404089e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
404189e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
4042f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
4043f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
4044f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
4045f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
4046f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
4047f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
4048f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
4049f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
405051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
405151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
405251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
405351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
405451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
405551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
405651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
405751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
405851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
405951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
4060c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
4061a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
4062a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
4063c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
4064c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
4065395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
4066395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
4067395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL)
4068395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
40693ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
407076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
407176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
407276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
407376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
407476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
407576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
407676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
407776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
407876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
407976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
408076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
408176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
408276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
408376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
408476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
408576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
408676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
408776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
408876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
408976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
409076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
409176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
409276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
409376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
40948213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
40958213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
40968213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
40978213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
40988213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
40998213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
41008213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
41018213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
41028213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
41038213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
41048213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
41058213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
41068213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
41071ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
41081ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
41091ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
41101ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
41111ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
4112c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
4113c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
4114c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
41151ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
41161ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
41171ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
41181ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
41191ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
41201ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
41211ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
41221ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
41231ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
41241ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
41251ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
41261ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
41271ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
41281ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
41291ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
41301ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
41311ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
41321ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
41331ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
41341ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
41351ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
41361ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
41371ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
41381ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
41391ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
41401ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
41411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
41421ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
41431ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
41441ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
41451ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
41461ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
41471ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
41481ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
4149326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
415050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
415150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
415250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
4153326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
4154326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
4155326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
4156326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
4157326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
4158326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
4159326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
416050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
416150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
416250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
416350f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
416450f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
416550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
416650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
416750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
4168326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
4169326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
4170326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
4171326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
4172326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
4173326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
4174326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
4175326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
4176326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
4177326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
4178326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
417989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
418089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
418189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
418289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
418389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
418489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
418589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
418689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
418789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
4188f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
4189f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
419089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
419189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
419289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
419389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
419489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
419589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
419689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
4197f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
4198f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
4199f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
4200f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
4201f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
4202f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
4203f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
4204f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
420589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
420689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
4207f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
4208f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
4209f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
421047a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
421147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
421247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
4213194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
4214194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Opc);
421547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
421647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
421747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
421847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
421947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
422047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
422147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
422247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
422347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
422447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
422547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
422647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
422747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
422847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
422947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
423047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
4231f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
4232f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
423347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
4234f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
4235f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
4236f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
423747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
4238194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
4239194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
4240194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
4241194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
4242194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
4243194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
4244194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
42454ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
4246194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
4247194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
4248194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
424947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
425047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
425147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
4252fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
4253fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
4254fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4255fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
4256fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
4257fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
425819cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
4259193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
4260193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
426119cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
4262e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
4263189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
4264189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
4265a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
4266a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
4267a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
4268a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
4269189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
4270a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
4271189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
4272f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
4273f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // encoding is selected.
4274f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    processInstruction(Inst, Operands);
4275f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
4276a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
4277a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
4278a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
4279a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
4280a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
4281fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
4282fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
4283e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
4284e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4285e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
4286e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
4287e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
4288e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
4289e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
4290e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
429116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4292e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
4293e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
4294e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
429516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4296e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
4297e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
4298e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
429947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
4300b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
430188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
430288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
4303f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
4304f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
430547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
430647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
4307194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
4308194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
4309194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
4310194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
4311fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
431216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4313c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
4314146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
4315fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
4316fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
43171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
4318ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
4319ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
4320ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
43211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
4322515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
43231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
4324515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
43251355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
4326515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
43271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
4328515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
43291355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
4330ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
4331ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4332ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
43331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
4334ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
43351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4336ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4337ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
4338ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
4339ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
4340ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
4341ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4342aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
4343ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4344ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
4345ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
434616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4347ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
4348ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
4349ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
4350b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
4351ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
4352ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
4353ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4354b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4355ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
4356ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4357ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
43581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
4359515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
43601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
4361515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
4362515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
4363b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4364515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4365515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
4366515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
4367515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
4368515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4369515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4370515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
43711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
4372515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
43731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
43746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
43756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
43766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
43776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
43786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
43796469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
43806469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
43816469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
43826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
43836469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
43846469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
43856469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
43866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
43876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4388515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
4389515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
4390b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4391515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
43926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
43936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
43946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
43956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
43966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4397642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
4398642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
4399642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
4400515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4401515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4402515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
44031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
4404515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
44051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
440618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4407515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4408515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
440938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
441058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
4411b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
441258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
44139e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
4414515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
4415515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
4416515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4417515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
441818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4419b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4420515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
4422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
4423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4424515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4425515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
44261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
4427515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
44281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
442918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4430515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
4431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
443218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
443358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
4434b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
443558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
4436b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4437515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
4438515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
4439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4440515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
444118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4442b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4443515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
444432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
444598447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
4446ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
444798447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
444832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
444998447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
4450ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
445198447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
4452eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
44532a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
4454515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4455515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4456515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
445790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
445890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
44599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
4460ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
446194b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
446294b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
446390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
4464ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
44653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
44660692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
44670692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
44683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
4469