ARMAsmParser.cpp revision 0afa0094afdfe589f407feb76948f273b414b278
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  }
11732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
118ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
119ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
12032869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
121ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1250692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1260692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
128a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
13089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
13143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
132f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
13343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
134f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
13543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1368bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
13743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1388bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1408bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
141f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
142f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
143f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
144f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
145f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
146f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
147f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
149c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
150580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
152293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
154251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
155ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
156ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
157a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
158a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
159a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool cvtT2StrdPre(MCInst &Inst, unsigned Opcode,
160a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &);
161eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  bool cvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
162eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
163ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  bool cvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
164ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
166ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1679ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1689ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
169548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
170548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
172ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1737b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1747b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
1842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
18514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
18614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
187623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
188623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
18988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
19088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
191189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
192189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
193189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
194f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  void processInstruction(MCInst &Inst,
195f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
196d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
197d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
198189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
199ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
20047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
201194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
202f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
203194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
204194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
20547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
20647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
207ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
20894b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
209ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
21032869205052430f45d598fba25ab878d8b29da2dEvan Cheng
211ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
212ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
213f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
214f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
215f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
216ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
217ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
221189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
22447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
22547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2271355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
229ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
23016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
23116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2323a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2333a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
235a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
236146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
237762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
2388462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
239d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
24089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITCondMask,
241fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
242fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
243cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
244706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
2458462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
2467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    PostIndexRegister,
247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
248a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
2498462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
2508d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
2510f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
2520f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
253e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
25492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ShiftedImmediate,
255580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ShifterImmediate,
2567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    RotateImmediate,
257293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    BitfieldDescriptor,
2588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
259a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
26224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
264a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
265a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
2688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
271fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
272fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
273fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
27489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
27589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
27689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
27789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
27889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
27989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
28089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
28189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
282a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
283a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
284a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
285a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
290a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
294a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
295a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
296a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2988155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
299cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
300cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
30116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3026a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
303a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
3100d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      unsigned ShiftImm;      // shift for OffsetReg.
3117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
3130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
316f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
317f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
318f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
322580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
323e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
324580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
325e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
326e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
327e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
328e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
329e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
330af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
33192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
33292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
33392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
33492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
335af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
339293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
340293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
341293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
342293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
34416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
345146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
346146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
347762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
348762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
349762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
350762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
351762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
3528462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
3538462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
3548462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
35589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    case ITCondMask:
35689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
35789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
3598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
361d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
362762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
363762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
364762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
3658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
3660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
3670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
36824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
3698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
371fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
373fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
374762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
375762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
376762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
377706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
378706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
379706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
380762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
381762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
382762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
3837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    case PostIndexRegister:
3847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
3857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
386584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
387584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
388584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
389a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
390a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
3910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
392580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    case ShifterImmediate:
393580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
3940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
395e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
396af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
397e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
39892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    case ShiftedImmediate:
399af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
40092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
4017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    case RotateImmediate:
4027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
4037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
404293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    case BitfieldDescriptor:
405293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
406293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
407762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
408762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
40916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
410762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
411762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
412762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
413762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
414a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
4168462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
4178462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4188462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
420fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
421fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
422fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
423fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
424fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
425a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
426a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
427a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
428a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
4316aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
4327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
433a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
434a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
4360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
4370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
43824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
4398d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
4408d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
441cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
442cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
443cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
444cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
445cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
446706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
447706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
448706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
449706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
450706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
451a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
452a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
453a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
454a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
455a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
456584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
457584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
458584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
459584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
460584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
461fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
462fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
4638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
464d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
46589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  bool isITMask() const { return Kind == ITCondMask; }
46689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  bool isITCondCode() const { return Kind == CondCode; }
4673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
468a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isImm8s4() const {
469a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (Kind != Immediate)
470a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
471a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
472a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!CE) return false;
473a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Value = CE->getValue();
474a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return ((Value & 3) == 0) && Value >= -1020 && Value <= 1020;
475a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
47672f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
47772f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (Kind != Immediate)
47872f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
47972f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
48072f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
48172f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
48272f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
48372f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
48472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
48572f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (Kind != Immediate)
48672f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
48772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
48872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
48972f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
49072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
49172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
4926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
4936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
4996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
50083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
50183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
50283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
50383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
50483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
50583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
50683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
50783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
50883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
50983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
51083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
51183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
51283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
51383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
51483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
51583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
5167c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
5177c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (Kind != Immediate)
5187c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
5197c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5207c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
5217c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
5227c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
5237c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
524f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
525f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (Kind != Immediate)
526f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
527f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
528f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
529f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
530f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
531f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
5324a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
5334a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (Kind != Immediate)
5344a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
5354a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5364a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
5374a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
5384a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
5394a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
540fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
541fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
542fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
543fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
544fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
545fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
546fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
547fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
548ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
549ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (Kind != Immediate)
550ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
551ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
552ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
553ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
554ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
555ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
556ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
557ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
558ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
559ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (Kind != Immediate)
560ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
561ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
562ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
563ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
564ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
565ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
56670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
56770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (Kind != Immediate)
56870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
56970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
57070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
57170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
57270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
57370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
574f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
575f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
576f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
577f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
578f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
579f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
580f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
581f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
582f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
583f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
584f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
585f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
586f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
587f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
588f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
589f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
5906bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
5916bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (Kind != Immediate)
5926bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
5936bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5946bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
5956bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
5966bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
5976bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
5986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
5996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
6006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
6016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
6036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
6046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
6056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
606c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
607c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (Kind != Immediate)
608c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
609c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
610c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
611c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
612c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
613c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
614b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
6158d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
6160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
6170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
61814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
619706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
62014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
621580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isShifterImm() const { return Kind == ShifterImmediate; }
622af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
623af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
6247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  bool isRotImm() const { return Kind == RotateImmediate; }
625293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  bool isBitfield() const { return Kind == BitfieldDescriptor; }
626f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; }
627f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
628f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
629f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
6307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemNoOffset() const {
6317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
632ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
6337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
6347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0;
635ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
6367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
6377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
638ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
6397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
6407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return true;
6417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
6427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
6457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
646039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
647039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Kind != Immediate)
648039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
649039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
650039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
651039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
652039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
653039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
654039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
6552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
6562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind != Memory)
6572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
6582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
6592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.ShiftType != ARM_AM::no_shift) return false;
6602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
6612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.OffsetRegNum) return true;
6622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetImm) return true;
6642fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6652fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
6662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
6672fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
6682fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind != Immediate && Kind != PostIndexRegister)
6692fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
6702fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind == PostIndexRegister)
6712fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
6722fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6732fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6742fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
6752fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
676251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
677251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
6782fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
6797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
6807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
681ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
6827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
6837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return false;
6847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
6857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6870da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
6880da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson           Val == INT32_MIN;
6897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
6907f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBB() const {
6917f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
6927f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
6937f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
6947f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
6957f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
6967f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  bool isMemTBH() const {
6977f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
6987f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach        Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm != 1)
6997f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach      return false;
7007f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return true;
7017f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
7027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
7037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum)
704ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
705ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
706ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
707ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  bool isT2MemRegOffset() const {
708ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative)
709ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
710ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    // Only lsl #{0, 1, 2, 3} allowed.
711ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    if (Mem.ShiftType == ARM_AM::no_shift)
712ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return true;
713ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    if (Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm > 3)
714ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach      return false;
715ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    return true;
716ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
7177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
7187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
7197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
7207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
7217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
72287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
72360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    return isARMLowRegister(Mem.BaseRegNum) &&
72460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum));
72560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
72660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
72760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
72860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
72960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
73060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
73160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (!Mem.OffsetImm) return true;
73260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
733ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
734ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
73538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
73638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
73738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
73838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
73938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
74038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (!Mem.OffsetImm) return true;
74138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
74238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
74338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
74448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
74548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
74648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
74748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
74848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
74948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (!Mem.OffsetImm) return true;
75048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
75148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
75248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
753ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
754ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP)
755ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
756ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
757ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (!Mem.OffsetImm) return true;
758ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
759ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
760505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
761a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool isMemImm8s4Offset() const {
762a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
763a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach      return false;
764a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // Immediate offset a multiple of 4 in range [-1020, 1020].
765a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    if (!Mem.OffsetImm) return true;
766a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
767a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return Val >= -1020 && Val <= 1020 && (Val & 3) == 0;
768a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
769b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  bool isMemImm0_1020s4Offset() const {
770b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
771b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach      return false;
772b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // Immediate offset a multiple of 4 in range [0, 1020].
773b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    if (!Mem.OffsetImm) return true;
774b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
775b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return Val >= 0 && Val <= 1020 && (Val & 3) == 0;
776b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
7777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
7787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
779f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
7807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
7817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
7827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
7834d2a00147d19b17d382644de0d6a1f0d3230e0e4Owen Anderson    return (Val == INT32_MIN) || (Val > -256 && Val < 256);
784f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
785f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  bool isMemPosImm8Offset() const {
786f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
787f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach      return false;
788f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    // Immediate offset in range [0, 255].
789f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    if (!Mem.OffsetImm) return true;
790f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
791f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    return Val >= 0 && Val < 256;
792f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
793a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemNegImm8Offset() const {
794a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
795a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
796a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [-255, -1].
797a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (!Mem.OffsetImm) return true;
798a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
799a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return Val > -256 && Val < 0;
800a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
801a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  bool isMemUImm12Offset() const {
802a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
803a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
804a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // and we reject it.
805a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (Kind == Immediate && !isa<MCConstantExpr>(getImm()))
806a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return true;
807a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
808a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
809a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return false;
810a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Immediate offset in range [0, 4095].
811a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (!Mem.OffsetImm) return true;
812a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
813a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    return (Val >= 0 && Val < 4096);
814a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
81609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
81709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
81809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
81909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    if (Kind == Immediate && !isa<MCConstantExpr>(getImm()))
82009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
82109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
8227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
823ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
8247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
8257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
8267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
8270da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
8287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
8297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
8307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Immediate)
8317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
8327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
833ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
8347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
83563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
836ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
8377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
838584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
8403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
84214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
84314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
84414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
84514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
8463483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
8473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
8483483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
8493483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
8503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8518462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
852345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
8538462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
85404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
85504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
8568462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
8578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
858fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
859fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
860fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
861fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
862fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
86389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
86489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
86589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
86689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
86789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
86889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
86989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
87089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
87189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
87289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
873fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
874fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
875fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
876fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
877fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
878d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
879d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
880d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
881d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
882d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
883a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
884a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
885a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
887a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
888af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
889e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
890af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
891af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
892af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
893e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
894af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
895e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
896e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
897af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
898152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
899af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
900af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
90192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
902af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
90392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
90492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
905580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
9060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
907580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
908580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
9090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
9100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
91187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
9127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
9135fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
9145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
9157729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
9167729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
91787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
91887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
9190f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
9200f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
9210f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
9220f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9230f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
9240f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
9250f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
9260f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
9287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
9307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
9317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
9327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
933293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
934293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
935293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
936293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
937293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
938293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
939293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
940293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
941293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
942293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
943293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
9443483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
9456b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9466b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
9476b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
9486b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
949a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addImm8s4Operands(MCInst &Inst, unsigned N) const {
950a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
951a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // FIXME: We really want to scale the value here, but the LDRD/STRD
952a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    // instruction don't encode operands that way yet.
953a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
954a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
955a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
956a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
95772f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
95872f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
95972f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
96072f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
96172f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
96272f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
96372f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
96472f39f8436848885176943b0ba985a7171145423Jim Grosbach
96572f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
96672f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
96772f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
96872f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
96972f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
97072f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
97172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
97272f39f8436848885176943b0ba985a7171145423Jim Grosbach
9736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
9746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9756b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
9766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
9776b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
97883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
97983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
98083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
98183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
98283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
98383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
9847c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9857c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
9867c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
9877c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
9887c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
98983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
99083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
99183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
99283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
993f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
994f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
995f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
996f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
997f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
998f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
999f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
1000f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
10014a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
10024a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
10034a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
10044a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
10054a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
10064a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
10074a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
10084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
1009fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1010fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1011fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
1012fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
1013fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
1014ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
1015ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1016ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
1017ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
1018ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach
1019ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
1020ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
1021ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    addExpr(Inst, getImm());
102270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
102370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach
102470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
102570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
102670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
102770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
102870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
102970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
103070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
1031ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
1032ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
1033f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
1034f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1035f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
1036f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1037f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1038f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
1039f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1040f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
1041f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
1042f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1043f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
1044f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
1045f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1046f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
10476bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
10486bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
10496bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
10506bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
10516bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
10526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
10533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
10543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
10553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
105616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1057c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
1058c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
1059c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
1060c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1061c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1062706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
1063706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1064706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
1065706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1066706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
10687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
10697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1070505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
1071505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
10727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
10737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
10747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
10757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetRegNum) {
10767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
10777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
10787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
10797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
10807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
10817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
10827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
10837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
10847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
1085dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach                              Mem.ShiftImm, Mem.ShiftType);
1086ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
10877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
10897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1090ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1091ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1092039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1093039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1094039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1095039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1096039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1097039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1098039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1099039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1100039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1101039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1102039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1103039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1104039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1105039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
11062fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
11072fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
11082fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
11092fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetRegNum) {
11102fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
11112fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
11122fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
11132fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
11142fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
11152fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
11162fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
11172fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
11182fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
11192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
11202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
11222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
11232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
11242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
11252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
11262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
11272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind == PostIndexRegister) {
11282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
11292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
11302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
11312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1132251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
11332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
11342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
11352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
11362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
11372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
11382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
11392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
11402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
11412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1142251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
11432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
11442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
11452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
11462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
11477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
11487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
11497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
11507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
11517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
11527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
11537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
11547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
11557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
11567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
11587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
11597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
1160a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  void addMemImm8s4OffsetOperands(MCInst &Inst, unsigned N) const {
1161a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1162a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
1163a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1164a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1165a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  }
1166a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
1167b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  void addMemImm0_1020s4OffsetOperands(MCInst &Inst, unsigned N) const {
1168b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1169b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
1170b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
1171b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1172b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1173b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  }
1174b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
11757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
11767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
11777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
11787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1180ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1181ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1182f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1183f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1184f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach  }
1185f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach
1186a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
1187f0eee6eca8c39b11b6a41d9b04eba8985655df77Jim Grosbach    addMemImm8OffsetOperands(Inst, N);
1188a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1189a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1190a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1191a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1192a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // If this is an immediate, it's a label reference.
1193a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    if (Kind == Immediate) {
1194a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      addExpr(Inst, getImm());
1195a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
1196a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach      return;
1197a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    }
1198a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
1199a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
1200a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
1201a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1202a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1203a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach  }
1204a8307dd1c9279cbde1f3497e530d2ed9d014a0c5Jim Grosbach
12057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
12067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
120709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
120809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    if (Kind == Immediate) {
120909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
121009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
121109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
121209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
121309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
121409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
12157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
12167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
12187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
121992b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
12207f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBBOperands(MCInst &Inst, unsigned N) const {
12217f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
12227f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12237f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
12247f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
12257f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
12267f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  void addMemTBHOperands(MCInst &Inst, unsigned N) const {
12277f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    assert(N == 2 && "Invalid number of operands!");
12287f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12297f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
12307f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  }
12317f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
12327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
12337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
12347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
12350d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                     Mem.ShiftImm, Mem.ShiftType);
12367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
12387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
12397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1240d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
1241ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
1242ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    assert(N == 3 && "Invalid number of operands!");
1243ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1244ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
1245ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mem.ShiftImm));
1246ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach  }
1247ab899c1bcca7f1cc85342c3a686464ba4af035dfJim Grosbach
12487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
12497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
12507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
12517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
125214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
12533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
125460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
125560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
125660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
125760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
125860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
125948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
126048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
126138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
126238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
126338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0;
126438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
126538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
126638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
126738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
126848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
126948ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
127048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0;
127148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
127248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
127360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
127460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1275ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1276ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1277ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
1278ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1279ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1280ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1281ecd858968384be029574d845eb098d357049e02eJim Grosbach
12827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
12837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
12847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
12857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
12867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
12877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
128863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
12897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
12907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1291f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1292ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
12937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
12947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
12957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1296f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1297f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1298f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1299f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1300f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1301f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1302f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1303f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1304f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1305f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1306f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1307f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1308ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1309ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1320b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1321b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
132289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
132389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ARMOperand *Op = new ARMOperand(ITCondMask);
132489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
132589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
132689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
132789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
132889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
132989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
13303a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
13313a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
1332345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1333345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1334345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
13353a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1336345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1337345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1338fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
1339fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
1340fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1341fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1342fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1343fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1344fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1345fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1346fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
1347fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
1348fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1349fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1350fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1351fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1352fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1353fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1354d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
1355d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
1356d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1357d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1358d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1359d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1360d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1361d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
13623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
13633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
1364762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1365762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1366762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1367762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
13683a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1369a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1370a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
137150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
13723a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
1373762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1374762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1375762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
13763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1379e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1380e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1381e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1382e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1383e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
1384e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
1385af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1386af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1387af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1388af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1389e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1390e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1391e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1392e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1393e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
139492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
139592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
139692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
139792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
139892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
1399af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1400af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1401af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
140292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
140392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
140492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
140592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
140692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1407580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
14080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
1409580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ARMOperand *Op = new ARMOperand(ShifterImmediate);
1410580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1411580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
14120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
14130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
14140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
14150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
14160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
14177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
14187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    ARMOperand *Op = new ARMOperand(RotateImmediate);
14197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
14207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
14217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
14227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
14237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
14247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1425293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1426293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
1427293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    ARMOperand *Op = new ARMOperand(BitfieldDescriptor);
1428293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1429293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1430293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1431293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1432293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1433293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1434293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
14357729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
14365fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1437cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
14380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
14390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1440d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Regs.front().first))
14410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
1442d300b94e51cf8c91928a66478c387c1c3d76faabJim Grosbach    else if (ARMMCRegisterClasses[ARM::SPRRegClassID].
1443275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
14440f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
14450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
14460f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
14475fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
14487729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
144924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1450cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1451cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1452cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
14538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
14548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
14558d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
14563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
14573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
1458762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1459762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1460762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
14613a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1462cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1463cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
14647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
14657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
14667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
14677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
14680d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
14697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
14703a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
14713a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
1472762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
14737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetImm = OffsetImm;
14747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetRegNum = OffsetRegNum;
1475762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
14760d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Op->Mem.ShiftImm = ShiftImm;
14777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.isNegative = isNegative;
14787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
14797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
14807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
14817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
148216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1483f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1484f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
1485f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
14867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
14877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARMOperand *Op = new ARMOperand(PostIndexRegister);
14887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
1489f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
1490f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
1491f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
1492762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1493762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
14943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1495a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1497706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
1498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
1499706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1503706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1504a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1505a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1506a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
1507a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1508a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1509a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1510a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1511a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1513584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
1515584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1516584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1517584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1518584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1519584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1520a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1522a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1523a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1524b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1525fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
1526fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
15276a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1528fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1529d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
1530d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1531d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
153289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ITCondMask: {
153389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)",
153489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)",
153589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(tee)", "(eee)" };
153689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
153789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
153889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
153989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
1540fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
1541fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1542fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1543fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
1544fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1545fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
1549fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
1550fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1551fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1552706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
1553706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1554706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
1555fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
15566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
15577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << " base:" << Mem.BaseRegNum;
15586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1559fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
15607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  case PostIndexRegister:
1561f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
1562f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
1563f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
1564f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
1565f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
1566f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
15677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
1568a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
1569a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1570a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1571a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1572a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1573a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1574a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1575a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1576a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1577fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
157850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1579fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1580580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  case ShifterImmediate:
1581580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1582580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
1583e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
1584e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
158592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1586af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedReg.SrcReg
1587af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1588af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << RegShiftedReg.ShiftReg << ", "
1589af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1590e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
15910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
159292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  case ShiftedImmediate:
159392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
1594af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedImm.SrcReg
1595af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1596af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
159792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
159892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
15997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  case RotateImmediate:
16007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
16017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
1602293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  case BitfieldDescriptor:
1603293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1604293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
1605293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
16060f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
16070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
16080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
16098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
16108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
16115fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
16125fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
16137729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
16147729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
16157729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
16168d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
16178d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
16188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
16198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
16208d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1621fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1622fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1623fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1624fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1625fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
16263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
16273483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
16283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
16293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
16303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
16313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
16323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
16333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
163469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
163569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
16361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
1637bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1638bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1639bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1640bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
16419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1642e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1643e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
16443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
16451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
164618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
16477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
1648d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1649a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1650a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
16510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
16520c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
16530c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
16540c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
16550c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
16560c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
16570c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
16580c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
16590c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
16600c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
16610c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
16620c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
166369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1664b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1665e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1666e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1667d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
166819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
166919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
167019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
167119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
167219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
16730d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
16740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
16750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
16760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
16770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
16780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
16790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
16800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
16810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
16820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
16830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
16840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
16850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
16860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
16870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
16880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
16890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
169019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
16910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1692e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1693e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1694e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1695e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1696e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1697eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1698e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1699e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1700e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1701e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1702e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1703e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1704e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1705e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1706e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1707e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1708e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1709e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1710e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1711e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1712e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1713e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
171419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
171519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
171619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
171719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1718e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1719e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
172019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
172119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
172219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
172319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1724e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1725e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1726e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1727e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1728e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1729e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1730e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
173119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
173219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1733e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1734e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
17351355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
1736e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
173719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
173819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
173919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
174019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
174119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
174219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1743e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
174419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
174519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1746e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1747e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
174892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
174992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1750af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
17510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
175292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
175392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
175492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
17550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
175619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
17570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
17580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
17590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
176050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
176150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
176250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1763e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1764e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1765e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
176650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
17671355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1768e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
17691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
1770e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
177150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1772d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
177350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1774a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1775e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1776e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
177750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
177850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1779e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
178099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
178199e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
178250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1783a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1784a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1785fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1786fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1787fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1788fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1789e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1790e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1791e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1792e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1793e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1794fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1795e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1796e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1797e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1798e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1799e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1800e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1801e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1802e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1803e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1804e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1805e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1806e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1807e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1808e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1809e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1810e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1811fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1812e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1813e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1814e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1815e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1816e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1817e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1818e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1819e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1820e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1821e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1822e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1823e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1824e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1825e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1826e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1827e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
182889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
182989df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
183089df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
183189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
183289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
183389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
183489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
183589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
183689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
183789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
183889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
183989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
184089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
184189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
184289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
184389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
184489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
184589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
184689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
184789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
184889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
184989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
185089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
185189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
185289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
185389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
185489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
185589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
185689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
185789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
185889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
185989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
186089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
186189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
186289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
186343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
1864fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1865fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1866f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
186743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1868e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1869e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1870e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1871e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1872fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1873e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1874f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1875e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1876e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1877fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1878f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1879fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1880fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
188143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
1882fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1883fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1884f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
188543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1886fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1887fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1888fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1889fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1890fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1891fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1892f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1893fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1894fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1896f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1897e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1898e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1899d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// For register list parsing, we need to map from raw GPR register numbering
1900d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// to the enumeration values. The enumeration values aren't sorted by
1901d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach// register number due to our using "sp", "lr" and "pc" as canonical names.
1902d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbachstatic unsigned getNextRegister(unsigned Reg) {
1903d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // If this is a GPR, we need to do it manually, otherwise we can rely
1904d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // on the sort ordering of the enumeration since the other reg-classes
1905d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // are sane.
1906d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
1907d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Reg + 1;
1908d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  switch(Reg) {
1909d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  default: assert(0 && "Invalid GPR number!");
1910d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R0:  return ARM::R1;  case ARM::R1:  return ARM::R2;
1911d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R2:  return ARM::R3;  case ARM::R3:  return ARM::R4;
1912d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R4:  return ARM::R5;  case ARM::R5:  return ARM::R6;
1913d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R6:  return ARM::R7;  case ARM::R7:  return ARM::R8;
1914d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R8:  return ARM::R9;  case ARM::R9:  return ARM::R10;
1915d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R10: return ARM::R11; case ARM::R11: return ARM::R12;
1916d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::R12: return ARM::SP;  case ARM::SP:  return ARM::LR;
1917d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  case ARM::LR:  return ARM::PC;  case ARM::PC:  return ARM::R0;
1918d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
1919d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach}
1920d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
1921d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach/// Parse a register list.
192250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
19231355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
192418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1925a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1926e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
1927d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '{' token.
1928d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc RegLoc = Parser.getTok().getLoc();
192916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1930d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Check the first register in the list to see what register class
1931d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // this is a list of.
1932d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  int Reg = tryParseRegister();
1933d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Reg == -1)
1934d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "register expected");
1935d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
1936d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  MCRegisterClass *RC;
1937d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
1938d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::GPRRegClassID];
1939d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
1940d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::DPRRegClassID];
1941d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
1942d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
1943d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  else
1944d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(RegLoc, "invalid register in register list");
1945e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1946d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // The reglist instructions have at most 16 registers, so reserve
1947d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // space for that many.
1948d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SmallVector<std::pair<unsigned, SMLoc>, 16> Registers;
1949d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // Store the first register.
1950d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
1951d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
1952d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // This starts immediately after the first register token in the list,
1953d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // so we can see either a comma or a minus (range separator) as a legal
1954d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  // next token.
1955d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  while (Parser.getTok().is(AsmToken::Comma) ||
1956d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach         Parser.getTok().is(AsmToken::Minus)) {
1957d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Parser.getTok().is(AsmToken::Minus)) {
1958d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      Parser.Lex(); // Eat the comma.
1959d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      SMLoc EndLoc = Parser.getTok().getLoc();
1960d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      int EndReg = tryParseRegister();
1961d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (EndReg == -1)
1962d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "register expected");
1963d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // If the register is the same as the start reg, there's nothing
1964d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // more to do.
1965d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (Reg == EndReg)
1966d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        continue;
1967d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // The register must be in the same register class as the first.
1968d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (!RC->contains(EndReg))
1969d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "invalid register in register list");
1970d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Ranges must go from low to high.
1971d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      if (getARMRegisterNumbering(Reg) > getARMRegisterNumbering(EndReg))
1972d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        return Error(EndLoc, "bad range in register list");
1973d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
1974d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      // Add all the registers in the range to the register list.
1975d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      while (Reg != EndReg) {
1976d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg = getNextRegister(Reg);
1977d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
1978d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      }
1979d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      continue;
1980d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    }
1981d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Parser.Lex(); // Eat the comma.
1982d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    RegLoc = Parser.getTok().getLoc();
1983d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    int OldReg = Reg;
1984d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Reg = tryParseRegister();
1985d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (Reg == -1)
19862d539691a1e4b9d61853aa99d1a5580dc88595dbJim Grosbach      return Error(RegLoc, "register expected");
1987d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // The register must be in the same register class as the first.
1988d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (!RC->contains(Reg))
1989d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "invalid register in register list");
1990d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // List must be monotonically increasing.
1991d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (getARMRegisterNumbering(Reg) <= getARMRegisterNumbering(OldReg))
1992d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "register list not in ascending order");
1993d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register lists must also be contiguous.
1994d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // It's OK to use the enumeration values directly here rather, as the
1995d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    // VFP register classes have the enum sorted properly.
1996d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
1997d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach        Reg != OldReg + 1)
1998d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach      return Error(RegLoc, "non-contiguous register range");
1999d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    Registers.push_back(std::pair<unsigned, SMLoc>(Reg, RegLoc));
2000d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  }
2001d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach
2002d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2003d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RCurly))
2004d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach    return Error(E, "'}' expected");
2005d0588e2a2ed1f7570f13b78c2042855dc4afae10Jim Grosbach  Parser.Lex(); // Eat '}' token.
2006e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
200750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
200850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
2009d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
2010d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
201143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
2012f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
201343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2014706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2015706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2016706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2017706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
2018706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2019706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
2020706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
2021706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
2022032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
2023706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
2024032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
2025706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
2026706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
2027032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
2028706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
2029032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
2030706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
2031706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
2032706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
2033706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2034706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
2035f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
2036706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
2037706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2038706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
2039f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
2040706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
2041706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
204243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
2043a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
204443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2045a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2046a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2047a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2048a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
2049a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2050a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
2051a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
2052a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
2053a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
2054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
2055a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
2056a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
2057a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2058a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
2059a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
2060a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
2061a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
2062a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2063a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
2064a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2065a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2066a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2067a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
2068a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
2069584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
2070584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
207143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
2072584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
207343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2074584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
2075584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
2076584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2077584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
2078584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2079584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
2080584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
2081584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
2082b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
2083584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
2084584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
2085584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2086584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
2087584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
2088584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2089584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
2090584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2091584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
2092584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
2093b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
2094584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
2095584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
2096584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
2097584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
20984b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
2099584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
2100584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
2101584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
2102bf841cf3360558d2939c9f1a244a7a7296f846dfJim Grosbach        FlagsVal = 8; // No flag
21034b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
2104584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
210556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
210656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
2107584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
2108584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
2109584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
2110584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
2111584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
2112584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
2113584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
2114584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2115584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
2116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
2117584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
2118584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
2119584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
2120584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
2121584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
2122584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
2123584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2124584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
2125584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
2126584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
2127584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2128584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
2129584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
2130584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
2131584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
2132584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
2133584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
2134584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
2135a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
2136a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2137f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2138f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
2139f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
2140f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2141f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2142f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2143f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2144f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2145f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
2146f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
2147f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
2148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
2149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
2150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
2153f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2154f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
2155f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2156f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2157f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2158f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2159f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
2160f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2161f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
2162f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
2163f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2164f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
2165f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2166f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2167f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2168f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
2169f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
2170f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2171f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2172f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
2173f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
2174f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
2175f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
2176f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2177f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2178f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
2179f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2180f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
2181f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
2182f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2183c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2184c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2185c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2186c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
2187c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2188c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2189c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2190c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2191c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
2192c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
2193c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
2194c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
2195c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
2196c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2197c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
2198c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2199c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2200c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2201c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
2202c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
2203c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
2204c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
2205c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
2206c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2207580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
2208580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
2209580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
2210580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
2211580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
2212580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2213580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2214580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
2215580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
2216580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2217580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2218580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2219580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2220580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
2221580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
2222580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
2223580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
2224580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
2225580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
2226580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
2227580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2228580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2229580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2230580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
2231580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2232580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
2233580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2234580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2235580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2236580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2237580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
2238580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2239580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
2240580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2241580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2242580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
2243580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2244580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2245580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2246580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
2247580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
2248580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2249580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2250580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2251580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
2252580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
2253580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2254580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
2255580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
2256580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2257580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
22580afa0094afdfe589f407feb76948f273b414b278Owen Anderson    // asr #32 encoded as asr #0, but is not allowed in Thumb2 mode.
22590afa0094afdfe589f407feb76948f273b414b278Owen Anderson    if (isThumb() && Val == 32) {
22600afa0094afdfe589f407feb76948f273b414b278Owen Anderson      Error(E, "'asr #32' shift amount not allowed in Thumb mode");
22610afa0094afdfe589f407feb76948f273b414b278Owen Anderson      return MatchOperand_ParseFail;
22620afa0094afdfe589f407feb76948f273b414b278Owen Anderson    }
2263580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
2264580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
2265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2266580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
2267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
2268580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2269580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
2270580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2271580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2272580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
2273580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
2274580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2275580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
2276580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
2277580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
22787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
22797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
22807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
22817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
22827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
22847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
2285326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (Tok.isNot(AsmToken::Identifier))
2286326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
22877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
2288326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR")
2289326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    return MatchOperand_NoMatch;
22907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
22917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
22927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
22937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
22947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
22957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
22967e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
22977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
22987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
22997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
23007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
23017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
23027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
23037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
23047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
23057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
23067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
23077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
23087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
23097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
23107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
23117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
23127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
23137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
23147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
23157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
23167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
23177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
23187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
23197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
23207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
23217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
23227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
23237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
23247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
23257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2326293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2327293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2328293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
2329293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
2330293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2331293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2332293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2333293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2334293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2335293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2336293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
2337293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2338293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
2339293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2340293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2341293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2342293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
2343293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2344293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
2345293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2346293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2347293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2348293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
2349293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
2350293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
2351293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
2352293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2353293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2354293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2355293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2356293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
2357293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
2358293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
2359293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2360293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2361293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2362293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2363293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2364293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2365293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2366293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2367293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2368293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
2369293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
2370293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2371293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2372293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2373293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
2374293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2375293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
2376293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2377293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2378293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2379293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
2380293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
2381293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
2382293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
2383293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2384293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2385293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2386293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2387293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
2388293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2389293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
2390293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
2391293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
23927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
23937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2395f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
2396f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
2397f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
23987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
23997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
24007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
24017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
24027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
24037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
24047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
240516578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
24067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
24077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
24087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
24097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
24107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
24117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
241216578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
24137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
24147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
24157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
24167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
24177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
24187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
24197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
24207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
24217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
24227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
24237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
24247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2425f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
2426f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
24270d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
24280d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
24290d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
24300d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
24310d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
2432f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
2433f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
2434f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
24357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
24367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
24377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
24387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2439251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2440251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2441251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2442251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
2443251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
2444251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
2445251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
2446251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
2447251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
2448251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2449251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
2450251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
2451251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
2452251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
2453251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
2454251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2455251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
2456251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
2457251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
2458251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
2459251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
2460251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2461251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
2462251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
2463251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2464251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
2465251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
2466251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
2467251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2468251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
2469251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
2470251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
2471251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
2472251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
2473251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
2474251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2475251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
2476251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
2477251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2478251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
2479251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2480251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2481251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2482251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
2483251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
2484251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
2485251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
2486251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
2487251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2488251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
2489251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
2490251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
2491251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2492251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2493251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
2494251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
2495251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
2496251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
2497251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
2498251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
2499251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
2500251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2501251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2502251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2503251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
2504251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
2505251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2506251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
2507251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
2508251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2509a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2LdrdPre - Convert parsed operands to MCInst.
2510a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2511a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2512a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
2513a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
2514a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2515a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
2516a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2517a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
2518a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
2519a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
2520a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
2521a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
2522a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
2523a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2524a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
2525a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
2526a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
2527a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// cvtT2StrdPre - Convert parsed operands to MCInst.
2528a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2529a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2530a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachbool ARMAsmParser::
2531a77295db19527503d6b290e4f34f273d0a789365Jim GrosbachcvtT2StrdPre(MCInst &Inst, unsigned Opcode,
2532a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach             const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2533a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Create a writeback register dummy placeholder.
2534a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(0));
2535a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt, Rt2
2536a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2537a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
2538a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
2539a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[4])->addMemImm8s4OffsetOperands(Inst, 2);
2540a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // pred
2541a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2542a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return true;
2543a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
2544a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
2545eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// cvtLdWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
2546eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2547eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2548eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbachbool ARMAsmParser::
2549eeec025cf5a2236ee9527a3312496a6ea42100c6Jim GrosbachcvtLdWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
2550eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2551eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2552eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
2553eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  // Create a writeback register dummy placeholder.
2554eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2555eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
2556eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
2557eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2558eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach  return true;
2559eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach}
2560eeec025cf5a2236ee9527a3312496a6ea42100c6Jim Grosbach
2561ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// cvtStWriteBackRegT2AddrModeImm8 - Convert parsed operands to MCInst.
2562ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2563ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2564ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbachbool ARMAsmParser::
2565ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim GrosbachcvtStWriteBackRegT2AddrModeImm8(MCInst &Inst, unsigned Opcode,
2566ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2567ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  // Create a writeback register dummy placeholder.
2568ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2569ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2570ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm8OffsetOperands(Inst, 2);
2571ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2572ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach  return true;
2573ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach}
2574ee2c2a4f98c4a6fa575dcdd1bcc3effd1432a7c7Jim Grosbach
25751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2576ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2577ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2578ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
25791355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2580ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2581ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2582ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
2583ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2584ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2585ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
25867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2587ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2588ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2589ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2590ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
25919ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
25929ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
25939ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
25949ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
25959ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
25969ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
25979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
25989ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
25999ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
26009ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
26019ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
26029ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
26039ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
26049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
26059ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
26069ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
26079ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
2608548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
2609548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2610548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2611548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
2612548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
2613548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2614548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
2615548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2616548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2617548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
2618548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2619548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
2620548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
2621548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
26221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2623ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2624ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2625ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
26261355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2627ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2628ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2629ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2630548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2631548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2632548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
26337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
26347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
26357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
26367b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
26377b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
26387b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
26397b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
26407b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
26417b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26427b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
26437b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
26447b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
26457b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
26467b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
26477b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
26487b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
26497b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
26507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
26517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
26527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
26537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
26547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
26557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
26587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
26597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
26607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
26617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
26627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
26637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
26647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2665ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2666ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2667ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2668ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
26697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
2670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2671ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2672ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
26737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
26747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2676aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2677ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2678ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
26797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
26807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
26817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
26827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
26837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
26847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
26857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
26867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
2687aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
26887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
26897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
26907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
26917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
26927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
26937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
26947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
26957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
26967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
26977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
26987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
26997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
27007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
27017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
27027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2703ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2704ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2705ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2706ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
27077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
2708ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2709ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2710ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
27117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
27127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2713ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2714ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
27157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2716ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
27177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
27187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
27197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
27207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
27217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2722ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2723ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2724ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2725ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
27262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
27272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
27282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
27292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
27302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
27312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
27322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
27332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
27342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
27352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
27362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
27372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
27382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
27392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
27402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
27412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
27422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
27432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
274414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
274514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
274614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
274714605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
274814605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
274914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
275014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
275114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
275214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
275314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
275414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
275514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
275614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
275714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
275814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
275914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
276014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
276114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
2762623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
2763623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2764623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2765623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
2766623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
2767623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2768623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2769623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
2770623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2771623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
2772623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2773623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
2774623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
2775623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
277688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
277788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
277888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
277988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
278088ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
278188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
278288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
278388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
278488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
27857a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
27867a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
27877a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
27887a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
278988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
27907a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
279188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
279288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
279388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
279488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
279588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
27967a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // If we have a three-operand form, use that, else the second source operand
27977a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // is just the destination operand again.
27987a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  if (Operands.size() == 6)
27997a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
28007a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  else
28017a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    Inst.addOperand(Inst.getOperand(0));
280288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
280388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
280488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
280588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
2806623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
2807e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
28089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
280950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
28107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2811762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
281218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
2813a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
2814762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
2815b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
2816a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
281718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
28181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
28197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
28207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
2821a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
28220571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
28230571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
28240571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
28257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
28260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
28277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
2828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
2829b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
2830a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
28317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
28327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             0, false, S, E));
283303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
2834fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
2835fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    // operand. It's rather odd, but syntactically valid.
2836fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
2837fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
2838fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach      Parser.Lex(); // Eat the '!'.
2839fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach    }
2840fb12f35545481e8b42bd547bc37d220ffee77f86Jim Grosbach
28417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
28427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
284350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
28447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
28457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
284650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
28477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If we have a '#' it's an immediate offset, else assume it's a register
28487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset.
28497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
28507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '#'.
28517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
285250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
28530da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
28547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
28557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
28567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
285705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
28587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
28597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
28607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
28617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
28627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
28637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
28647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
28650da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
28660da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
28670da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
28680da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
28690da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
28707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
28717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
28727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
28737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
28747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
287505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
28767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
28777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
28787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
28797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             ARM_AM::no_shift, 0, false, S,E));
2880a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
28817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
28827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
28837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
28847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
28857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
2886762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
28877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
28887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
28899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
2890d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
28917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
28927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
28937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
28947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
28957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
28967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
28977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
28987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
28997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
29009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
29017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
29027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
29037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
29047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
29057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
29067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
29077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
29080d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
29097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
29107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
29110d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
29127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
29139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
291416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
29157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
29167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
29177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
29187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
29197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
29207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
29217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
29220d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                           ShiftType, ShiftImm, isNegative,
29237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
29247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2925f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
2926f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
2927f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
2928f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
2929f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
2930f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
29319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
29329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
29339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
29349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
29357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
2936a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
2937a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
29387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
29397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
29407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
29417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
294218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2943a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2944a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
294538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
2946a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
29470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
2948a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
29490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
2950a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
29510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
2952a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
29530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
2954a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
29550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
2956a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
29577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
2958b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
2959a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
29607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
29617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
29627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
29637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
29647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
29657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
29667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (HashTok.isNot(AsmToken::Hash))
29677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
29687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
29699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
29707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
29717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
29727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
29737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
29747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
29757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
29767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
29777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
29787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
29797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
29807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
29817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
29827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
29837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
29847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
29857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
2986a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2987a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
2988a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2989a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
29909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
29919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
29921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2993fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
2994762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
2995fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2996fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
2997fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
2998f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2999f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
3000fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
3001f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
3002f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
3003f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
3004f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
3005f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
3006fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
3007a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
3008146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
3009146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
301050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
301119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
30121355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
301350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
30140d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
301519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
30160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
301719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
301819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
3019e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
3020e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
3021e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
302219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
302367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
302467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
3025515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
3026515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
3027515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
3028762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
3029515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
303050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
3031762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
303250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
303350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
303450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
3035a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
30361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
3037d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
30381355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
303963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
3040079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
3041079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
3042762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
3043b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
304463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
3045515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
3046515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
304750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
304863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
304963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (!CE) {
305063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      Error(S, "constant expression expected");
305163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      return MatchOperand_ParseFail;
305263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
305363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    int32_t Val = CE->getValue();
305463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (isNegative && Val == 0)
305563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
3056762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
305750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
305850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
305963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
30609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
30619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
30627597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
30637597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
30647597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
30651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
30669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
30679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
30687597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
30697597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
30709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
30719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
30727597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
30737597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
30749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
30757597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
30769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
30779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
3078a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
3079a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
3080a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
30811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
30827597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
30831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
30847597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
30859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
30869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
30878a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
30889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
30899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
30909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
30919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
30929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
30939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
30949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
30959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
30969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
30977597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
30989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
30997597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
31009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
31019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
31029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
31039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
31049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
31059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
31069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
31079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
31089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
31099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
31109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
31119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
31129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
31139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
3114352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
3115352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
3116352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
3117badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
311889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
31191355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
31205f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
31215f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
312289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
312389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
3124352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
3125352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
3126a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
3127352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
3128badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
3129352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
3130352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
31315f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
31325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
31335f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
31345f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
31355f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
31365f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
31375f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
31385f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
3139352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
3140badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
31413f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
31423f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
3143ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
314471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
314504d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
31462f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
31473f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
31483f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
31493f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
31503f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
31513f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
31523f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
31533f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
31543f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
31553f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
31563f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
31573f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
31583f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
31593f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
31603f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
31613f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
31623f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
31633f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
31643f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
31653f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
31663f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
31673f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
31683f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
31693f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
317052925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
3171345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3172352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
3173352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
3174352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
317500f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
31765f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
31775f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
31785f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
3179e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
3180e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
3181352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
3182352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
3183352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
3184352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
3185a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
3186a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
3187a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
3188a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
3189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
3190a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
3191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
3192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
3193a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
3194a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
3195a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
3196a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
3197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
3198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
320089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
320189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
320289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
320389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
320489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
320589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
3206352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
3207352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
32083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
32093771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
32103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
32113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
32123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
3213fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
32141355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
3215fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
3216eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
3217eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
32183443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      Mnemonic == "add" || Mnemonic == "adc" ||
3219eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
3220d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "orr" || Mnemonic == "mvn" ||
3221eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
3222d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach      Mnemonic == "sbc" || Mnemonic == "eor" || Mnemonic == "neg" ||
32233443ed525a3bce98bacabb5aa8e67bee6def3b09Jim Grosbach      (!isThumb() && (Mnemonic == "smull" || Mnemonic == "mov" ||
3224d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "mla" || Mnemonic == "smlal" ||
3225d5d0e81a4bec76a56a1e7b2326ed12bfcbcab9b9Jim Grosbach                      Mnemonic == "umlal" || Mnemonic == "umull"))) {
3226eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
3227fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
3228eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
32293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
3230eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
3231eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
3232eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
3233eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
3234ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "setend" ||
3235ad2dad930d450d721209531175b0cbfdc8402558Jim Grosbach      (Mnemonic == "clrex" && !isThumb()) ||
32360780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
32374af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") &&
32384af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
32394af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
32404af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
32411ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumbOne())) {
32423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
3243fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  } else
32443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
3245fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
3246fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  if (isThumb()) {
3247fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
324863b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
3249fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
3250fb9cffea4a650d7f60d2c24741656c52c2185945Jim Grosbach  }
3251badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
3252badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3253d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
3254d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
325520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
325620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
3257d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3258d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
3259d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
3260d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
3261d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
3262d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
3263d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
3264d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
3265d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
32668adf62034a874adacff158e8adc9438cb3e67c01Owen Anderson  if (Mnemonic == "mov" && Operands.size() > 4 && !isThumb() &&
3267d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
3268d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
3269d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3270d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
32713912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
32723912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
32733912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
32743912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
32753912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
32763912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
32773912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
32783912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
327972f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
328020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
328120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
328220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
3283f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (((isThumb() && Mnemonic == "add") ||
3284f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach       (isThumbTwo() && Mnemonic == "sub")) &&
3285f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
328672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
328772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
328872f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
328920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
329020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
329120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
329272f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
3293f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // For Thumb2, add/sub immediate does not have a cc_out operand for the
3294f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  // imm0_4095 variant. That's the least-preferred variant when
329520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
329620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
329720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
3298f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  if (isThumbTwo() && (Mnemonic == "add" || Mnemonic == "sub") &&
3299f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Operands.size() == 6 &&
330020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
330120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
330220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
330320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
330420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
330520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
330620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
330720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // check against T3.
330820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
330920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
331020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
331120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
331220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
331320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
331420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
331564944f48a1164c02c15ca423a53919682a89074cJim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) &&
331620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
331720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
331820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
331920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
332020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
332120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
332220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
332320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
332420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
332564944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // The thumb2 multiply instruction doesn't have a CCOut register, so
332664944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // if we have a "mul" mnemonic in Thumb mode, check if we'll be able to
332764944f48a1164c02c15ca423a53919682a89074cJim Grosbach  // use the 16-bit encoding or not.
332864944f48a1164c02c15ca423a53919682a89074cJim Grosbach  if (isThumbTwo() && Mnemonic == "mul" && Operands.size() == 6 &&
332964944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
333064944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
333164944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
333264944f48a1164c02c15ca423a53919682a89074cJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isReg() &&
333364944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // If the registers aren't low regs, the destination reg isn't the
333464944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // same as one of the source regs, or the cc_out operand is zero
333564944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // outside of an IT block, we have to use the 32-bit encoding, so
333664944f48a1164c02c15ca423a53919682a89074cJim Grosbach      // remove the cc_out operand.
333764944f48a1164c02c15ca423a53919682a89074cJim Grosbach      (!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
333864944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) ||
333964944f48a1164c02c15ca423a53919682a89074cJim Grosbach       !inITBlock() ||
334064944f48a1164c02c15ca423a53919682a89074cJim Grosbach       (static_cast<ARMOperand*>(Operands[3])->getReg() !=
334164944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[5])->getReg() &&
334264944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[3])->getReg() !=
334364944f48a1164c02c15ca423a53919682a89074cJim Grosbach        static_cast<ARMOperand*>(Operands[4])->getReg())))
334464944f48a1164c02c15ca423a53919682a89074cJim Grosbach    return true;
334564944f48a1164c02c15ca423a53919682a89074cJim Grosbach
334664944f48a1164c02c15ca423a53919682a89074cJim Grosbach
334720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
3348f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
3349f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
3350f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
3351f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
3352f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
3353f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
3354f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
335572f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
335672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
335772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
335872f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
33593912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
3360d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
3361d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
3362d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3363badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
3364badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
3365badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3366badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
3367badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
3368ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
3369badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3370352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
3371352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
3372a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
3373352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
337489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
33751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
337689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
3377badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
33780c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
33790c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
33800c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
33810c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
33820c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
33830c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
3384ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
3385ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
338689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
338789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
338889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
338989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
339089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
339189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
3392f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
3393f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
3394f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
3395f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
3396f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
339789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
339889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
339989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
340089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
340189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
3402f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
340389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
340489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
340589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
340689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
340789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
3408f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
340989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
341089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
3411ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
3412ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
34139717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
34143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
34153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
34163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
34173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
34183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
34193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
34203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
34213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
34221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
34233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
342433c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
342533c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
342633c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
342733c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
3428ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
342933c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
343033c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
3431c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
3432c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
3433c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
3434c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
3435c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
3436c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
3437c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
343833c16a27370939de39679245c3dff72383c210bdJim Grosbach
34393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
3440f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
3441f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
34423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
3443f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
3444f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
34453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
34463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
34473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
3448f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
3449f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
34503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
3451f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
3452badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
3453345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3454a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
3455a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
3456a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
3457a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
3458a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
3459a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3460a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3461345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
34625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
34635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
34645747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
3465a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
3466a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
34674d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // For now, we're only parsing Thumb1 (for the most part), so
34684d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // just ignore ".n" qualifiers. We'll use them to restrict
34694d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // matching when we do Thumb2.
347081d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    if (ExtraToken != ".n") {
347181d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Start);
347281d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, Loc));
347381d2e3901eed4bd70f551df8935c9ff224ccef6fJim Grosbach    }
34745747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
34755747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
34765747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
34775747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3478a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
34791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
3480cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
3481cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
3482cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
3483a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
3485b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
3486a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
34881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
3489cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
3490cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
3491cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
3492a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
3493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
349416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3495cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3496cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
349734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
3498cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
3499146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
350034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
3501ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3502d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
3503d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
3504d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
350520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
350620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
350720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
350820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
350920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
3510ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3511ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
3512ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
3513ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
3514ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3515cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
3516cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
3517cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
3518cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // a CondCode operand in the list. If we're trying to match the label
3519cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // version, remove the CondCode operand here.
3520cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
3521cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
3522cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3523cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
3524cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
3525cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
3526857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
3527857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
3528857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
3529857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
3530857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
3531857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
3532857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3533857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3534857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3535857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
3536857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
3537857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3538857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
3539857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
3540857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
3541934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
3542934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // end. Convert it to a token here.
3543934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
3544934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3545934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3546934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3547934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    if (CE && CE->getValue() == 0) {
3548934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
3549934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3550934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
3551934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
3552934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
3553934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
35549898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
3555ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3556ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3557189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
3558aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
3559aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
3560aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
3561aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
3562aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
3563aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
3564aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
3565aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
3566aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
3567aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
3568aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
3569aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
3570aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
3571aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
3572aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
3573aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
3574aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
3575aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
357676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// Check if the specified regisgter is in the register list of the inst,
357776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach// starting at the indicated operand number.
357876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbachstatic bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
357976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
358076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
358176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (OpReg == Reg)
358276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return true;
358376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
358476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  return false;
358576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach}
358676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach
3587f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
3588f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
3589f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
3590f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
3591f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[];
3592f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
3593f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) {
3594f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
3595f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
3596f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3597189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
3598189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
3599189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
3600189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3601f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3602f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
3603f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
3604b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // NOTE: In Thumb mode, the BKPT instruction has the interesting property of
3605b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // being allowed in IT blocks, but not being predicable.  It just always
3606b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  // executes.
3607b6b7f515e2b90c9f9b6cdd5b9648121f6ad2b3a1Owen Anderson  if (inITBlock() && Inst.getOpcode() != ARM::tBKPT) {
3608f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
3609f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
3610f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
3611f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
3612a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
3613f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
3614f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
3615f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
3616f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
3617f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
3618f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
3619f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
3620f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
3621f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
3622f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
3623f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
3624f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
3625f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
3626f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
3627f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
3628f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
3629f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
3630c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
3631f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
3632f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
363351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tB &&
363451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson             Inst.getOpcode() != ARM::t2B)
3635f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
3636f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3637189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
36382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
36392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
36402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
3641189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
3642189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3643189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
3644189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3645189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
3646189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3647189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
3648189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3649189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
365014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
365114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
365214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
365314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
365414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
365514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
365614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
365714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
365814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
365953642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
366053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
3661189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
3662189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3663189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3664189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
3665189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
366614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3667189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
3668189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3669189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3670fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
3671fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
3672fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
3673fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
3674fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
3675fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
3676fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
3677fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
367800c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
3679fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
368093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
368176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we're parsing Thumb2, the .w variant is available and handles
368276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // most cases that are normally illegal for a Thumb1 LDM
368376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instruction. We'll make the transformation in processInstruction()
368476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // if necessary.
368576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    //
368693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
368793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
368893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
36897260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
36907260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
36917260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
3692aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
369376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
3694aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
3695aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
369693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
369776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
369893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
369993b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
370076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If we should not have writeback, there must not be a '!'. This is
370176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // true even for the 32-bit wide encodings.
3702aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
37037260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
37047260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
37057260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
370693b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
370793b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
370893b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
370976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::t2LDMIA_UPD: {
371076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
371176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      return Error(Operands[4]->getStartLoc(),
371276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "writeback operator '!' not allowed when base register "
371376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                   "in register list");
371476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
371576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
37166dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
3717aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3718aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
3719aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3720aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
37216dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
37226dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
37236dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
3724aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3725aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
3726aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3727aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
37286dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
37296dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
37301e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
37311e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
37328213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase) && !isThumbTwo())
37331e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
37341e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
37351e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
37361e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
3737189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3738189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3739189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
3740189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
3741189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3742f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser::
3743f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
3744f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3745f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
3746f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
3747f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
3748f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
3749f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
3750f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
3751f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
3752f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
3753f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
3754f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
3755f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
3756f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
3757f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
3758f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
3759f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3760f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
3761f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
3762f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
3763f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
3764f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
3765f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
3766f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
3767f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
3768f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
3769f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
3770f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
3771f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
3772f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
3773f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
3774f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
3775f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3776f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
3777f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
3778f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
377989e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
37800f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
37810f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
37820f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
37830f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
37840f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
378589e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
378689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
3787f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach  case ARM::tSUBi8:
3788f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
3789f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
3790f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
3791f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    // to encoding T1 if <Rd> is omitted."
3792f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
3793f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach      Inst.setOpcode(ARM::tSUBi3);
3794f67e8554bf4808ad447ffb5d2deebbb10b810391Jim Grosbach    break;
379551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::tB:
379651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb conditional branch outside of an IT block is a tBcc.
379751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
379851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::tBcc);
379951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
380051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  case ARM::t2B:
380151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    // A Thumb2 conditional branch outside of an IT block is a t2Bcc.
380251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock())
380351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      Inst.setOpcode(ARM::t2Bcc);
380451f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    break;
3805c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
3806a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
3807a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
3808c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
3809c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
3810395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
3811395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
3812395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL)
3813395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
38143ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
381576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  case ARM::tLDMIA: {
381676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // If the register list contains any high registers, or if the writeback
381776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
381876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // instead if we're in Thumb2. Otherwise, this should have generated
381976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    // an error in validateInstruction().
382076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
382176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool hasWritebackToken =
382276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
382376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
382476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    bool listContainsBase;
382576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
382676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (!listContainsBase && !hasWritebackToken) ||
382776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        (listContainsBase && hasWritebackToken)) {
382876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
382976ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      assert (isThumbTwo());
383076ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
383176ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // If we're switching to the updating version, we need to insert
383276ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      // the writeback tied operand.
383376ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach      if (hasWritebackToken)
383476ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach        Inst.insert(Inst.begin(),
383576ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach                    MCOperand::CreateReg(Inst.getOperand(0).getReg()));
383676ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    }
383776ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach    break;
383876ecc3d35b4d16afb016bb14e29e12802b968716Jim Grosbach  }
38398213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  case ARM::tSTMIA_UPD: {
38408213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // If the register list contains any high registers, we need to use
38418213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // the 32-bit encoding instead if we're in Thumb2. Otherwise, this
38428213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    // should have generated an error in validateInstruction().
38438213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
38448213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    bool listContainsBase;
38458213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    if (checkLowRegisterList(Inst, 4, Rn, 0, listContainsBase)) {
38468213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
38478213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      assert (isThumbTwo());
38488213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach      Inst.setOpcode(ARM::t2STMIA_UPD);
38498213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    }
38508213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach    break;
38518213c96655e955a0b63b05580bc2f6a55be26083Jim Grosbach  }
38521ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVi: {
38531ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
38541ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
38551ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
38561ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(1).getImm() <= 255 &&
3857c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        ((!inITBlock() && Inst.getOperand(2).getImm() == ARMCC::AL &&
3858c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach         Inst.getOperand(4).getReg() == ARM::CPSR) ||
3859c2d3164ab467bdfa8508b93177e69b99626cd8e2Jim Grosbach        (inITBlock() && Inst.getOperand(4).getReg() == 0)) &&
38601ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
38611ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
38621ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't in the same order for tMOVi8...
38631ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
38641ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
38651ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
38661ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
38671ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
38681ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
38691ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
38701ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
38711ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
38721ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
38731ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
38741ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  case ARM::t2MOVr: {
38751ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
38761ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    // request the 32-bit variant, transform it here.
38771ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
38781ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
38791ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(2).getImm() == ARMCC::AL &&
38801ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        Inst.getOperand(4).getReg() == ARM::CPSR &&
38811ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
38821ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
38831ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      // The operands aren't the same for tMOV[S]r... (no cc_out)
38841ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      MCInst TmpInst;
38851ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.setOpcode(Inst.getOperand(4).getReg() ? ARM::tMOVSr : ARM::tMOVr);
38861ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
38871ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
38881ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2));
38891ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
38901ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach      Inst = TmpInst;
38911ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    }
38921ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach    break;
38931ad60c2adc9ed765a968747d0c548cda53bfd384Jim Grosbach  }
3894326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  case ARM::t2SXTH:
389550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2SXTB:
389650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTH:
389750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach  case ARM::t2UXTB: {
3898326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // If we can use the 16-bit encoding and the user didn't explicitly
3899326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    // request the 32-bit variant, transform it here.
3900326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
3901326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        isARMLowRegister(Inst.getOperand(1).getReg()) &&
3902326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        Inst.getOperand(2).getImm() == 0 &&
3903326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach        (!static_cast<ARMOperand*>(Operands[2])->isToken() ||
3904326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach         static_cast<ARMOperand*>(Operands[2])->getToken() != ".w")) {
390550f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      unsigned NewOpc;
390650f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      switch (Inst.getOpcode()) {
390750f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      default: llvm_unreachable("Illegal opcode!");
390850f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTH: NewOpc = ARM::tSXTH; break;
390950f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2SXTB: NewOpc = ARM::tSXTB; break;
391050f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTH: NewOpc = ARM::tUXTH; break;
391150f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      case ARM::t2UXTB: NewOpc = ARM::tUXTB; break;
391250f1c37123968b7f57068280483ec78f6ff7973eJim Grosbach      }
3913326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      // The operands aren't the same for thumb1 (no rotate operand).
3914326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      MCInst TmpInst;
3915326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.setOpcode(NewOpc);
3916326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0));
3917326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1));
3918326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3919326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4));
3920326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach      Inst = TmpInst;
3921326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    }
3922326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach    break;
3923326efe58918d3f0a431d07938054870fcd0e240fJim Grosbach  }
392489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
392589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
392689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
392789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
392889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
392989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
393089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
393189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
393289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
3933f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
3934f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
393589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
393689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
393789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
393889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
393989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
394089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
394189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
3942f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3943f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
3944f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
3945f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
3946f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
3947f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
3948f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
3949f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
395089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
395189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
3952f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
3953f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
3954f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
395547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
395647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
395747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
3958194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
3959194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Opc);
396047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
396147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
396247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
396347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
396447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
396547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
396647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
396747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
396847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
396947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
397047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
397147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
397247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
397347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
397447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
397547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
3976f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
3977f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
397847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
3979f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
3980f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
3981f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
398247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
3983194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
3984194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
3985194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
3986194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
3987194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
3988194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
3989194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
39904ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
3991194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
3992194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
3993194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
399447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
399547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
399647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
3997fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
3998fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
3999fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4000fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
4001fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
4002fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
400319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
4004193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
4005193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
400619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
4007e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
4008189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
4009189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
4010a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
4011a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
4012a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
4013a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
4014189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
4015a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
4016189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
4017f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
4018f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // encoding is selected.
4019f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    processInstruction(Inst, Operands);
4020f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
4021a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
4022a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
4023a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
4024a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
4025a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
4026fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
4027fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
4028e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
4029e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4030e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
4031e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
4032e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
4033e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
4034e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
4035e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
403616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4037e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
4038e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
4039e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
404016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4041e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
4042e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
4043e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
404447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
4045b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
404688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
404788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
4048f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
4049f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
405047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
405147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
4052194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
4053194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
4054194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
4055194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
4056fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
405716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4058c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
4059146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
4060fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
4061fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
40621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
4063ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
4064ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
4065ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
40661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
4067515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
40681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
4069515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
40701355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
4071515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
40721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
4073515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
40741355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
4075ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
4076ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4077ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
40781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
4079ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
40801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4081ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4082ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
4083ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
4084ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
4085ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
4086ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4087aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
4088ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4089ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
4090ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
409116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4092ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
4093ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
4094ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
4095b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
4096ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
4097ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
4098ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
4099b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4100ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
4101ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
4102ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
41031355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
4104515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
41051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
4106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
4107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
4108b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4109515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4110515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
4111515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
4112515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
4113515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4114515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4115515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
41161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
4117515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
41181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
41196469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
41206469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
41216469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
41226469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
41236469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
41246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
41256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
41266469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
41276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
41286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
41296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
41306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
41316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
41326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4133515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
4134515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
4135b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4136515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
41376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
41386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
41396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
41406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
41416469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
4142642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
4143642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
4144642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
4145515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4146515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4147515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
41481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
4149515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
41501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
415118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4152515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
4153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
415438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
415558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
4156b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
415758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
41589e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
4159515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
4160515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
4161515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4162515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
416318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4164b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4165515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4166515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
4167515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
4168515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4169515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4170515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
41711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
4172515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
41731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
417418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
4175515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
4176515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
417718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
417858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
4179b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
418058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
4181b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
4182515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
4183515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
4184515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
4185515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
418618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
4187b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
4188515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
418932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
419098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
4191ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
419298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
419332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
419498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
4195ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
419698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
4197eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
41982a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
4199515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
4200515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
4201515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
420290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
420390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
42049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
4205ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
420694b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
420794b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
420890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
4209ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
42103483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
42110692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
42120692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
42133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
4214