ARMAsmParser.cpp revision e8606dc7c878d4562da5e3e5609b9d7d734d498c
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
10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h"
1192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling#include "ARMAddressingModes.h"
127597212abced110723f2fee985a7d60557c092ecEvan Cheng#include "ARMMCExpr.h"
13b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h"
143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
16c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
17c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
19642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h"
25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2875ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
34ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "ARMGenSubtargetInfo.inc"
36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
53e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int TryParseRegister();
54bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
5550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
5750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
58ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
59ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   ARMII::AddrMode AddrMode);
60fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
617597212abced110723f2fee985a7d60557c092ecEvan Cheng  bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
65a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                            enum ARM_AM::ShiftOpc &ShiftType,
699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
72762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
73762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool ParseShift(enum ARM_AM::ShiftOpc &St,
750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                  const MCExpr *&ShiftAmount, SMLoc &E);
76ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
827036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
837c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
84fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                               MCStreamer &Out);
85fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes  void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
86fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
8716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
89ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
93ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
94ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
9532869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
96ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
97ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
9832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
99ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1030692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1040692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocNumOperand(
109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocRegOperand(
111f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseMemBarrierOptOperand(
1138bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  OperandMatchResultTy tryParseProcIFlagsOperand(
1158bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  OperandMatchResultTy tryParseMSRMaskOperand(
1178bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode2Operand(
119ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
120ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode3Operand(
121ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
123ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
124ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
125ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
128ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
129ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
130ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
131ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
132f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach
133ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
134ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
135ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    : TargetAsmParser(), STI(_STI), Parser(_Parser) {
136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
13732869205052430f45d598fba25ab878d8b29da2dEvan Cheng
138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
139ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
141ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
14238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1439898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
145ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
14616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
14716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1483a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
152146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
153762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1548462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
155d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
156fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
157fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
158cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
159706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
161584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
162a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
167e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
1680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Shifter,
1698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
171a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
17324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
174a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
175a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
181706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
182706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
183706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
184706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
185fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
186fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
188fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
190a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
193584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
194584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
195584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
196584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
203a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2058155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
206cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
207cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
20816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2096a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
211ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARMII::AddrMode AddrMode;
212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2132637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      union {
2142637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
2152637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
2162637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      } Offset;
217146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
2180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
219146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
22050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Preindexed       : 1;
22150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Postindexed      : 1;
22250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned OffsetIsReg      : 1;
22350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Negative         : 1; // only used when OffsetIsReg is true
22450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Writeback        : 1;
225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
2300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    } Shift;
231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
233e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } ShiftedReg;
237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
23816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
239146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
240146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
241762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
242762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
243762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2468462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2478462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2508462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
251762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
252d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2568d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
25924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2608d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
261fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
262fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
268706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
269706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
270706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
272762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
277a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
278a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
2790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
2800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    case Shifter:
2810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      Shift = o.Shift;
2820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
284e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftedReg = o.ShiftedReg;
285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
28816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
2978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
2988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
299fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
300fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
301fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
302fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3106aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
31724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
320cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
321cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
322cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
323cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
324cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
325706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
326706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
327706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
328706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
329706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @name Memory Operand Accessors
3416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @{
342ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ARMII::AddrMode getMemAddrMode() const {
343ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return Mem.AddrMode;
344ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
3456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemBaseRegNum() const {
3466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.BaseRegNum;
3476ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegNum() const {
3496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3506ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.RegNum;
3516ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3526ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemOffset() const {
3536ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(!Mem.OffsetIsReg && "Invalid access!");
3546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.Value;
3556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegShifted() const {
3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.OffsetRegShifted;
3596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemShiftAmount() const {
3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftAmount;
3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc getMemShiftType() const {
3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftType;
3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPreindexed() const { return Mem.Preindexed; }
3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPostindexed() const { return Mem.Postindexed; }
3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemNegative() const { return Mem.Negative; }
3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemWriteback() const { return Mem.Writeback; }
3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @}
3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
376fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
379d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
3816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
3826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
3836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
3846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
3866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
3876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
3886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
3896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
3906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
3916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
3926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
3946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
3956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
3966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
397b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
3988d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
3990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
4000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
40114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
402706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
40314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
4040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool isShifter() const { return Kind == Shifter; }
405e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  bool isShiftedReg() const { return Kind == ShiftedRegister; }
406ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool isMemMode2() const {
407ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode2)
408ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
409ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
410ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg())
411ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return true;
412ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
413ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemNegative() &&
414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
415ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
416ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
417ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
418ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (!CE) return false;
419ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Value = CE->getValue();
420ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
421ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // The offset must be in the range 0-4095 (imm12).
422ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Value > 4095 || Value < -4095)
423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return true;
426ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
427ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool isMemMode3() const {
428ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode3)
429ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
430ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
431ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
432ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (getMemOffsetRegShifted())
433ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return false; // No shift with offset reg allowed
434ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
435ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
436ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
437ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemNegative() &&
438ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
439ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
440ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
441ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
442ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (!CE) return false;
443ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Value = CE->getValue();
444ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
445ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // The offset must be in the range 0-255 (imm8).
446ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Value > 255 || Value < -255)
447ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
448ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
449ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
450ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
45187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  bool isMemMode5() const {
4524b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
4534b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar        getMemNegative())
45487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
455ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4564b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
457ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
458ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
45987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    // The offset must be a multiple of 4 in the range 0-1020.
46087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    int64_t Value = CE->getValue();
46187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
46287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
463505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  bool isMemMode7() const {
464505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!isMemory() ||
465505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPreindexed() ||
466505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPostindexed() ||
467505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemOffsetIsReg() ||
468505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemNegative() ||
469505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemWriteback())
470505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
471505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
472505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
473505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!CE) return false;
474505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
475505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (CE->getValue())
476505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
477505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
478505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
479505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
480f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeRegThumb() const {
4814b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
482f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
483d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    return true;
484f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
485f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeImmThumb() const {
4864b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
487ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
488ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4894b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
490ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
491ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
492ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    // The offset must be a multiple of 4 in the range 0-124.
493ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint64_t Value = CE->getValue();
494ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    return ((Value & 0x3) == 0 && Value <= 124);
495ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
496584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
497a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
4983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
4993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
50014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
50114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
50214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
50314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
5043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
5053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
5063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
5073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
5083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
510345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
5118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
51204f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
51304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
5148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
5158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
516fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
517fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
518fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
519fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
520fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
521fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
522fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
523fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
525fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
526d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
527d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
528d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
529d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
530d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
533a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
534a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
536e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
537e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
538e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
539e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert((ShiftedReg.ShiftReg == 0 ||
540e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach            ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) &&
541e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach           "Invalid shifted register operand!");
542e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
543e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
544e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
545e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
546e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
547e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
5480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  void addShifterOperands(MCInst &Inst, unsigned N) const {
5490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
5500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
5510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
5520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
5530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
55487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
5557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
5565fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
5575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
5587729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
5597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
56087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
56187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
5620f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
5630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
5670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
5746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
5756b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
5766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
5776b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
5786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
5796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
5806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
5813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
5823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
5833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
58416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
586706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
587706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
588706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
589706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
590505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
591505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
592505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
593505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
594505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
5951866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay    (void)CE;
596505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert((CE || CE->getValue() == 0) &&
597505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes           "No offset operand support in mode 7");
598505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
599505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
600ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
601ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(isMemMode2() && "Invalid mode or number of operands!");
602ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
604ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg()) {
606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
607ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
608ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
609ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      int64_t ShiftAmount = 0;
611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (getMemOffsetRegShifted()) {
613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShOpc = getMemShiftType();
614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        const MCConstantExpr *CE =
615ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
616ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShiftAmount = CE->getValue();
617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      }
618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
620ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           ShOpc, IdxMode)));
621ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return;
622ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
623ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
624ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
625ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
626ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
627ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
628ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // the difference?
629ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
630ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(CE && "Non-constant mode 2 offset operand!");
631ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Offset = CE->getValue();
632ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
633ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Offset >= 0)
634ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
635ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           Offset, ARM_AM::no_shift, IdxMode)));
636ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    else
637ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
638ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                          -Offset, ARM_AM::no_shift, IdxMode)));
639ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
640ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
641ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
642ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(isMemMode3() && "Invalid mode or number of operands!");
643ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
644ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
645ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
646ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
647ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                                             IdxMode)));
652ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return;
653ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
654ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
655ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
656ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
657ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // the difference?
660ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(CE && "Non-constant mode 3 offset operand!");
662ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Offset = CE->getValue();
663ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
664ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Offset >= 0)
665ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
666ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           Offset, IdxMode)));
667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    else
668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           -Offset, IdxMode)));
670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
671ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
67214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
67314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
67416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6754b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6764b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
67792b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
67880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
67980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // the difference?
6804b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
681d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert(CE && "Non-constant mode 5 offset operand!");
682d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
683d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // The MCInst offset operand doesn't include the low two bits (like
684d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // the instruction encoding).
685d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    int64_t Offset = CE->getValue() / 4;
686d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    if (Offset >= 0)
687d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
688d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             Offset)));
689d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    else
690d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
691d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             -Offset)));
69214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
6933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
694f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
695f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
6964b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6974b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
698f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
699ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
700f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
701f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
7024b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
7034b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
704f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(CE && "Non-constant mode offset operand!");
705f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
706ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
707ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
709584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
710584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
711584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
712584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
713a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
714a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
715a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
716a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
717a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
718b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
719b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
7203a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
7213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
723345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
724345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
7253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
726345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
727345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
728fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
732fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
733fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
738fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
740fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
741fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
742fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
743fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
744d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
745d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
746d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
747d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
748d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
749d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
750d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
751d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
7523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
7533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
754762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
755762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
756762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
757762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
7583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
759a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
760a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
76150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
7623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
763762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
764762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
765762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
7663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
767a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
768a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
769e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
770e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
771e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
772e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
773e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
774e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
775e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftTy = ShTy;
776e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.SrcReg = SrcReg;
777e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftReg = ShiftReg;
778e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftImm = ShiftImm;
779e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
780e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
781e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
782e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
783e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
7840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
7850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
7860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    ARMOperand *Op = new ARMOperand(Shifter);
7870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->Shift.ShiftTy = ShTy;
7880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
7890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
7900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
7910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
7920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
7937729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
7945fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
795cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
7960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
7970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    if (ARM::DPRRegClass.contains(Regs.front().first))
7990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
8000f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    else if (ARM::SPRRegClass.contains(Regs.front().first))
8010f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
8020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
8030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
8045fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
8057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
80624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
807cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
808cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
809cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
8108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
8118d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
8128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
8133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
8143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
815762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
816762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
817762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
819cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
820cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
822ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               bool OffsetIsReg, const MCExpr *Offset,
823ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               int OffsetRegNum, bool OffsetRegShifted,
8240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               enum ARM_AM::ShiftOpc ShiftType,
8253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
8263a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
8273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
828023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((OffsetRegNum == -1 || OffsetIsReg) &&
829023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegNum must imply OffsetIsReg!");
830023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!OffsetRegShifted || OffsetIsReg) &&
831023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegShifted must imply OffsetIsReg!");
832d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert((Offset || OffsetIsReg) &&
833d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar           "Offset must exists unless register offset is used!");
834023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
835023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have shift amount without shifted register offset!");
836023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!Offset || !OffsetIsReg) &&
837023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have expression offset and register offset!");
838023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar
8393a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
840ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Op->Mem.AddrMode = AddrMode;
841762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
842762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
8432637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    if (OffsetIsReg)
8442637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.RegNum = OffsetRegNum;
8452637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    else
8462637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.Value = Offset;
847762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
848762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
849762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
850762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
851762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
852762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
853762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
85416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
855762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
856762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
858a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
859706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
860706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
861706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
862706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
863706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
864706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
865706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
866706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
867a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
868a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
874a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
875584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
876584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
877584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
878584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
879584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
880584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
881584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
882584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
883a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
884a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
885a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
887b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
888fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
889fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
8906a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
891fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
892d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
893d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
894d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
896fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
897fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
898fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
899fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
900fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
901584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
902584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
903584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
904fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
905fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
906fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
907706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
908706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
909706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
910fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
9116ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
912ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
913ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << " base:" << getMemBaseRegNum();
9146ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg()) {
9156ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:<register " << getMemOffsetRegNum();
9166ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      if (getMemOffsetRegShifted()) {
9176ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-type:" << getMemShiftType();
9186ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-amount:" << *getMemShiftAmount();
9196ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      }
9206ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    } else {
9216ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:" << *getMemOffset();
9226ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    }
9236ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg())
9246ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (offset-is-reg)";
9256ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPreindexed())
9266ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (pre-indexed)";
9276ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPostindexed())
9286ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (post-indexed)";
9296ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemNegative())
9306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (negative)";
9316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemWriteback())
9326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (writeback)";
9336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
934fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
935a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
936a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
937a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
938a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
939a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
940a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
941a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
942a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
944fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
94550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
946fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
9470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  case Shifter:
948e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
949e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
950e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
951e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    OS << "<so_reg"
952e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ShiftedReg.SrcReg
953e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
954e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ", " << ShiftedReg.ShiftReg << ", "
955e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
956e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
9570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
9580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
9590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
9600f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
9618d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
9628d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
9635fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
9645fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
9657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
9667729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
9677729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
9688d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
9698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
9708d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
9718d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
9728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
973fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
974fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
975fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
976fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
977fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
9783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
9803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
9813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
9833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
9853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
98669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
98769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
988bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  RegNo = TryParseRegister();
989bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
990bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
991bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
992bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
9939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
994e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
995e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
9963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
997e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() {
99818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
999a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1000d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1001a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1002a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
10030c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
10040c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
10050c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
10060c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
10070c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
10080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
10090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
10100c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
10110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
10120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
10130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
10140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
101569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1016b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1017e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1018e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1019d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
10200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// Try to parse a register name.  The token must be an Identifier when called,
10210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// and if it is a register name the token is eaten and the register number is
10220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// returned.  Otherwise return -1.
10230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson///
10240082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::TryParseShiftRegister(
10250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
10260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
10270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
10280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
10290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
10310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
10320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
10330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
10340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
10350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
10360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
10370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
10380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
10390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
10410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return true;
10420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1043e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1044e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1045e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1046e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1047e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1048e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  ARMOperand *PrevOp = (ARMOperand*)Operands.pop_back_val();
1049e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1050e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1051e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1052e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1053e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1054e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1055e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1056e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1057e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1058e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1059e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1060e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1061e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1062e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1063e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1064e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
1065e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (getParser().ParseExpression(ShiftExpr))
1066e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach        return Error(ImmLoc, "invalid immediate shift value");
1067e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1068e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
1069e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (!CE)
1070e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach        return Error(ImmLoc, "invalid immediate shift value");
1071e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1072e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1073e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1074e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1075e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1076e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1077e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
1078e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach        return Error(ImmLoc, "immediate shift value out of range");
1079e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1080e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
1081e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftReg = TryParseRegister();
1082e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
1083e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (ShiftReg == -1)
1084e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach        return Error (L, "expected immediate or register in shift operand");
1085e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else
1086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      return Error (Parser.getTok().getLoc(),
1087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
1088e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
10900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1091e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1092e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                                       ShiftReg, Imm,
10930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
10940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  return false;
10960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
10970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
109950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
110050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
110150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1102e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1103e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1104e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
110550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
110650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1107e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
1108e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int RegNo = TryParseRegister();
1109e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
111050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1111d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
111250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1113a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1114e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1115e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
111650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
111750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1118e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
111999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
112099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
112150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1122a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1123a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1124fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1125fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1126fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1128e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1129e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1130e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1131e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1132e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1133fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1134e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1135e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1136e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1137e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1138e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1139e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1140e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1141e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1142e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1143e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1144e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1145e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1146e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1147e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1148e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1149e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1150fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1151e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1152e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1153e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1154e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1155e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1156e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1157e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1158e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1159e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1160e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1161e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1162e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1163e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1164e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1165e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1166e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1167f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1168fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1169fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1170f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1171f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1172e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1173e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1174e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1175e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1176fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1177e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1178f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1179e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1180e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1181fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1182f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1183fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1184fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1185f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1186fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1188f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1189f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1190fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1191fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1192fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1195fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1196f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1200f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1203c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1204c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
120550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
120650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
120718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1208a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1209e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
121016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
12117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
12127729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
12135fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1214d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
12157729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1216e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
12177729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1218d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
121918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1220d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1221c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1222c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
122350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1224c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1225e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12261d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling    int RegNum = TryParseRegister();
1227c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1228c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
122950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1230c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1231d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1232e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1233e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1234e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1235e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1236e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1237e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1238e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1239e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1240e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1241e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1242e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
12437729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
12447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1245e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1246e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
124718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1248c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1249c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
125050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1251c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1252d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1253e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1254e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
125503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1256e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
12575fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1258e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1259e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12607caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
12618e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
12628e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
12637caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
12647caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
12657caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1266e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
12677729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
12687caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1269e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12708e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1271e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
127250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1273e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1274e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12758e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1276e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1277e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1278e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12798e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
12808e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1281e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1282e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
128350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
128450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1285d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1286d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1287f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1288f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1289f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1290706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1291706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1292706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1293706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1294706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1295706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1296706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1297706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1298706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1300706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1301706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1302706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1303706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1304706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1305706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1306706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1307f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1308706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1309706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1310706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1311f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1312706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1313706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
13148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1315a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1316a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1317a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1318a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1319a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1320a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1321a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1322a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1323a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1324a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1325a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1335a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1340a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1341584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1342584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1343584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1344584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1345584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1346584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1347584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1349584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1350584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1351584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1352584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef SpecReg = Mask.slice(Start, Next);
1355584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1356584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1357584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1358584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1359584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1360584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1361584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1362584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1363584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1364584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1365584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvq",  0x8) // same as CPSR_c
1366584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1367584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1368584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1369584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
13704b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1371584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1374584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
13754b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1376584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
137756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
137856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1379584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1380584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1381584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1382584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1383584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1384584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1385584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1386584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1387584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1388584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1389584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1390584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1391584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1392584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1393584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1394584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1395584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1396584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1397584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1398584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1399584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1400584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1401584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1402584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1403584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1404584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1406584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1407a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1408a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1409ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1410ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1411ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1412e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1413ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode2))
1415ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return MatchOperand_NoMatch;
1416ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1417ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return MatchOperand_Success;
1418ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1419ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1420ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1421ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1422ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1423ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1424ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1425ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode3))
1426ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1427ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1428ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return MatchOperand_Success;
1429ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1430ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1431ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1432ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1433ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1435ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1436ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1437ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1438ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1439ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1440ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1441ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1442ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1443ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1444ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1445ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1446ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1447ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1448ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1449ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1450ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1451ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1452ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1453ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1454ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1455ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1456ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1457ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1458ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1459ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1460ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1461ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1462ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1463ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1464ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1465ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1466ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1467ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1468ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1469ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1470ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1471ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1472ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1473ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1474ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1475ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1476ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1477ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1478ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1479ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1480ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1481ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1482ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1483ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1484ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1485ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1486ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1487ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1488ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1489ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1490ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1491e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
14929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
149350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling///
14949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
14959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
149650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
1497ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1498ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
150018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
1501a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
1502762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
1503b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
1504a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
150518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
1506550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1507550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
150850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1510e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int BaseRegNum = TryParseRegister();
1511e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (BaseRegNum == -1) {
1512550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
151350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1514550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1515a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15160571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
15170571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
15180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
15190571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    return true;
15200571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
1521a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
1522a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
1523a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
1524a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
1525a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
152605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  ARMOperand *WBOp = 0;
152705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  int OffsetRegNum = -1;
152805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  bool OffsetRegShifted = false;
15290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
153005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *ShiftAmount = 0;
153105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *Offset = 0;
1532a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
15349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
1535a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
1536a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
1537b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
153805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1539550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1540550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
154150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
154218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
1543550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
1544550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
154550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1546550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
1547762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
1548b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
155018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
1551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
1552ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      // None of addrmode3 instruction uses "!"
1553ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode3)
1554ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return true;
1555ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
155650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
155750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                     ExclaimTok.getLoc());
1558a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
1559b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
1560ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1561ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode2)
1562ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        Preindexed = false;
1563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
15640571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  } else {
15650571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    // The "[Rn" we have so far was not followed by a comma.
15660571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
156780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // If there's anything other than the right brace, this is a post indexing
156880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // addressing form.
1569762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
1570b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1571a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
157218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
157303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1574e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
157580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Postindexed = true;
157680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Writeback = true;
157750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1578550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
1579550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
158050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1581550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
158250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1583b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
158450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1585550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
158616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1587550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
158850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1589a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
159005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  }
1591e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
159205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  // Force Offset to exist if used.
159305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (!OffsetIsReg) {
159405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    if (!Offset)
159505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar      Offset = MCConstantExpr::Create(0, getContext());
1596ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  } else {
1597ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1598ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Error(E, "shift amount not supported");
1599ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
1600ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
1601a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
160205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1604ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Offset, OffsetRegNum, OffsetRegShifted,
1605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     ShiftType, ShiftAmount, Preindexed,
1606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Postindexed, Negative, Writeback, S, E));
160705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (WBOp)
160805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    Operands.push_back(WBOp);
160905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
161005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  return false;
1611a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1612a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
16139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
16149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
16159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
16169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
16179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
16189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
16199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
16209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1621762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
16220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                        enum ARM_AM::ShiftOpc &ShiftType,
16239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
16249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
16259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
1626762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
1627762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
16289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
16299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
16309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
16319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
163218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
1633762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
16349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
1635b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
16369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
16379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
1638b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
16399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
16409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
164118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
16429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
1643e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    SMLoc CurLoc = OffsetRegTok.getLoc();
1644e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    OffsetRegNum = TryParseRegister();
1645e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    if (OffsetRegNum != -1) {
1646550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
1647e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner      E = CurLoc;
1648762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
16499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
1650d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
165112f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling  // If we parsed a register as the offset then there can be a shift after that.
16529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
16539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
165418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
16559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
1656b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
16579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
165818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
1659762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
16603472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
16619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
16629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
16639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
16649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
16659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
166618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
16679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
16689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
166916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1670b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
16719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
16729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
16739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
1674762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
16759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
16769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
16779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
16789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
1679a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
1680a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
1681a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
1682a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
16830082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
16840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                              const MCExpr *&ShiftAmount, SMLoc &E) {
168518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
1687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
168838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
1689a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
16900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
1691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
16920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
1693a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
16940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
1695a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
16960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
1697a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
16980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
1699a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
1700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
1701b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
1702a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
17040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (St == ARM_AM::rrx)
17059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
1706a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
170818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
17099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
17109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
1711b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
17129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
17139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
17149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
1715a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1716a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
1717a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1718a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
17209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
1721e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1722fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
1723762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
1724fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1725fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
1726fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
1727f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1728f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
1729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
1730f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1731f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
1732f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
1733f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
1734f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
1735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
1737146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
1738146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
173950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
174067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Identifier:
174150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    if (!TryParseRegisterWithWriteBack(Operands))
174250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
17430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    if (!TryParseShiftRegister(Operands))
17440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
17450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1746e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1747e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
1748e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
174967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
175067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
1751515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
1752515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
1753515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
1754762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
175650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1757762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
175850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
175950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
176050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
1761a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
176250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseMemory(Operands);
1763d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
176450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseRegisterList(Operands);
1765d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
1766079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
1767079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1768762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1769b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
1770515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
1771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
177250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1773762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
177450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
177550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
17769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
17779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
17787597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
17797597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
17807597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
17819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (ParsePrefix(RefKind))
17829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
17839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17847597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
17857597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
17869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
17879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17887597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
17897597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
17909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
17917597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
17929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
17939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
1794a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1795a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1796a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17977597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
17987597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
17997597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
18007597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
18019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
18038a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
18049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
18059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
18079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
18089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
18099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
18129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
18137597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
18149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
18157597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
18169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
18179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
18189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
18199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
18219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
18239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
18249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
18259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
18279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
18289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
18299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
18319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
18329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
18339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
18349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
18359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
18369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
18379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
18399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
18409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
18419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
18429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
18439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
18459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
18469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
18489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
18499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
18519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
18549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
18559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
18579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
18589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
18599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
18609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
18619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
18629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
18649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
18689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
18699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
18709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
1871352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
1872352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
1873352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
1874badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
1875a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic,
1876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &PredicationCode,
1877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               bool &CarrySetting,
1878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &ProcessorIMod) {
1879352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
1880352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
1882352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1883badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
1884352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
1885352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
18868ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar  if (Mnemonic == "teq" || Mnemonic == "vceq" ||
18878ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "movs" ||
18888ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "svc" ||
18898ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
18908ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vmls" || Mnemonic == "vnmls") ||
18918ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacge" || Mnemonic == "vcge" ||
18928ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vclt" ||
18938ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacgt" || Mnemonic == "vcgt" ||
18948ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vcle" ||
18958ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
18968ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
1897d1f0bbee189ea7cd18d03c4f9f55d0a33b070814Jim Grosbach       Mnemonic == "vqdmlal" || Mnemonic == "bics"))
1898352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
1899badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
19003f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
19013f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
19023f00e317064560ad11168d22030416d853829f6eJim Grosbach  if (Mnemonic != "adcs") {
19033f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
19043f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
19053f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
19063f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
19073f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
19083f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
19093f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
19103f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
19113f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
19123f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
19133f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
19143f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
19153f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
19163f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
19173f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
19183f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
19193f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
19203f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
19213f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
19223f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
19233f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
19243f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
19253f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
192652925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
1927345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1928352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
1929352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
1930352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
1931352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
1932352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
1933352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
1934352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
1935352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
1936352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
1937352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
1938352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
1939352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1940a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
1941a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
1942a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
1943a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
1944a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
1945a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
1946a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
1947a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
1948a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
1949a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
1950a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
1951a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
1952a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
1953a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1954a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1955352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
1956352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
19573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
19583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
19593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
19603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
19613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
1962fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
1963fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
1964fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
1965eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
1966eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
1967eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
1968eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
1969be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
1970eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
1971eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
1972be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "eor" || Mnemonic == "smlal" ||
1973ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
1974eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
1975eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
1976eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
1977eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
19783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
1979eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
1980eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
1981eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
1982eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
1983e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes      Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
1984a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
19853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
19863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
19873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
19883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
1989fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
1990ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
1991fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
199263b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
1993fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
1994badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
1995badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1996badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
1997badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
1998badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1999badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
2000badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
2001badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  StringRef Head = Name.slice(Start, Next);
2002badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2003352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
2004352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
2005a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
2006352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
2007a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Head = SplitMnemonic(Head, PredicationCode, CarrySetting,
2008a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                       ProcessorIMod);
2009badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
20103a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
20119717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
20123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
20133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
20143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
20153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
20163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
20173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
20183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
20193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
20203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode);
20213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
20233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
20243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
20253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
20263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
20273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptCarrySet) {
20283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
20293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
20303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
20313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a carry set, but the user wrote one (or
20323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // misspelled another mnemonic).
20333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
20353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
20363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
20383771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
20393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
20403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
20413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
20423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a predication code, but the user wrote
20433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // one (or misspelled another mnemonic).
20443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
2046badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
2047345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2048a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
2049a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
2050a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
2051a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
2052a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
2053a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
2054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
2055a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
2056a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2057a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
2058a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2059a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2060345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
20615747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
20625747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
20635747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
2064a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
2065a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2066a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
20675747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
20685747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
20695747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
20705747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2071a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
2072fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (ParseOperand(Operands, Head)) {
2073cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
2074cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
2075cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
2076a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2077a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
2078b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
2079a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2080a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
2081fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      if (ParseOperand(Operands, Head)) {
2082cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
2083cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
2084cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
2085a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
2086a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
208716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2088cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2089cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
209034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
2091cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
2092146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
209334e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
20949898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
2095ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2096ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2097fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
2098fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
2099fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2100fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
2101fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
2102fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
2103193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResultTy MatchResult, MatchResult2;
2104193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2105193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  if (MatchResult != Match_Success) {
2106193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_InvalidOperand it might be some arithmetic instruction
2107193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that does not update the condition codes.  So try adding a CCOut operand
2108193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // with a value of reg0.
2109193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    if (MatchResult == Match_InvalidOperand) {
2110193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      Operands.insert(Operands.begin() + 1,
2111193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                      ARMOperand::CreateCCOut(0,
2112193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                                  ((ARMOperand*)Operands[0])->getStartLoc()));
2113193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2114193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (MatchResult2 == Match_Success)
2115193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult = Match_Success;
211644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      else {
211744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2118193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.erase(Operands.begin() + 1);
211944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete CCOut;
212044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      }
2121193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2122193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_MnemonicFail it might be some arithmetic instruction
2123193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that updates the condition codes if it ends in 's'.  So see if the
2124193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
2125193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // operand with a value of CPSR.
2126eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng    else if (MatchResult == Match_MnemonicFail) {
2127193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      // Get the instruction mnemonic, which is the first token.
2128193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
2129193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
2130193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        // removed the 's' from the mnemonic for matching.
2131193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
2132193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
213344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
213444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.erase(Operands.begin());
213544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete OldMnemonic;
213644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.insert(Operands.begin(),
2137193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateToken(MnemonicNoS, NameLoc));
2138193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.insert(Operands.begin() + 1,
2139193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
2140193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2141193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        if (MatchResult2 == Match_Success)
2142193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby          MatchResult = Match_Success;
2143193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        else {
214444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
214544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin());
214644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete OldMnemonic;
214744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.insert(Operands.begin(),
2148193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                          ARMOperand::CreateToken(Mnemonic, NameLoc));
214944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
215044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin() + 1);
215144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete CCOut;
2152193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        }
2153193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      }
2154193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2155193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  }
2156193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2157e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2158fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2159fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2160e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2161e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2162e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2163e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2164e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2165e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2166e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2167e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
216816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2169e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2170e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2171e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
217216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2173e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2174e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2175e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2176e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2177b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2178b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2179fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
218016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2181c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2182146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2183fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2184fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
2185515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
2186ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2187ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2188ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
2189ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
2190515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
2191515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
2192515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
2193515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2194515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
2195515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
2196515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
2197515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
2198ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2199ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2200ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2201ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
2202ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
2203ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2204ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2205ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2206ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2207ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2208ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2209ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2210aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2211ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2212ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2213ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
221416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2215ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2216ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2217ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2218b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2219ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2220ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2221ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2222b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2223ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2224ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2225ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2226515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
2227515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
2228515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2229515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2230515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2231b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2232515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2233515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2234515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2236515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2237515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2238515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2239515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
2240515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
2241515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
22426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
22436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
22446469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
22456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
22466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
22476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
22486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
22496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
22506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
22516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
22526469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
22536469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
22546469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
22556469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2256515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2257515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2258b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2259515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
22606469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
22616469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
22626469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
22636469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
22646469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2265642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2266642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2267642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2268515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2269515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2270515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2271515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
2272515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
2273515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
227418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2275515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2276515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
227738e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
227858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2279b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
228058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
22819e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2282515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2283515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2284515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2285515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
228618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2287b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2288515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2289515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2290515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2291515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2292515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2293515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2294515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
2295515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
2296515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
229718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2298515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2299515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
230018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
230158c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2302b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
230358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2304b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2305515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2306515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2307515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2308515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
230918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2310b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2311515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
231232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
2313ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (!isThumb())
2314ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
23152a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
231632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
2317ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (isThumb())
2318ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
23192a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2320eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
23212a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2322515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2323515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2324515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
232590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
232690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
23279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2328ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
2329ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2330ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
233190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2332ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
23333483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23340692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
23350692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
23363483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2337