ARMAsmParser.cpp revision ac79e4c82f201c30a06c2cd05baebd20f5b49888
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"
18642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h"
23ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h"
24c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
25fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
270c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
28345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
30ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
31ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
323a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
33146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
34146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
3516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
36ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
38d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  TargetMachine &TM;
39ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
41ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
46e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int TryParseRegister();
47bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
4850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
5050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
51ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
52ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   ARMII::AddrMode AddrMode);
53fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
547597212abced110723f2fee985a7d60557c092ecEvan Cheng  bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
58a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                            enum ARM_AM::ShiftOpc &ShiftType,
629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
65762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
66762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool ParseShift(enum ARM_AM::ShiftOpc &St,
680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                  const MCExpr *&ShiftAmount, SMLoc &E);
69ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
70515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
71515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
72515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
73515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
757036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
767c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
77fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                               MCStreamer &Out);
78fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes  void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
79fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
8016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
81a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
82a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
840692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
850692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
86a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
87a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
88a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
89f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocNumOperand(
90f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
91f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocRegOperand(
92f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
93f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseMemBarrierOptOperand(
948bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
95a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  OperandMatchResultTy tryParseProcIFlagsOperand(
968bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
97584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  OperandMatchResultTy tryParseMSRMaskOperand(
988bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
99ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode2Operand(
100ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
101ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode3Operand(
102ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
103ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
104ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
105ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
106ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
107ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
108ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
109ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
110ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
111ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
112ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
113f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach
114ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
115d73ada7d24832bc2a4c3965b8f00ffd951341acfDaniel Dunbar  ARMAsmParser(const Target &T, MCAsmParser &_Parser, TargetMachine &_TM)
116833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach    : TargetAsmParser(T), Parser(_Parser), TM(_TM) {
117833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach      // Initialize the set of available features.
118833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach      setAvailableFeatures(ComputeAvailableFeatures(
119833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach          &TM.getSubtarget<ARMSubtarget>()));
120833c93c7958dbbd9d648f331091fbfbeabf342e6Jim Grosbach    }
121ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
12238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1239898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
124ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
125ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
12616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
12716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1283a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
130a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
132146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
133762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1348462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
135d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
136fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
137fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
138cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
139706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1408462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
141584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
142a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1438462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1460f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
1470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Shifter,
1488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
149a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
151762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
15224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
153a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
154a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
155a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1568462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1578462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
160706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
161706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
163706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
166fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
167fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
168a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
169a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
170a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
171a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
172584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
173584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
174584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
175584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
177a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
181a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1848155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
185cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
186cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
18716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1886a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
190ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARMII::AddrMode AddrMode;
191a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
1922637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      union {
1932637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
1942637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
1952637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      } Offset;
196146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
1970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
198146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
19950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Preindexed       : 1;
20050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Postindexed      : 1;
20150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned OffsetIsReg      : 1;
20250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Negative         : 1; // only used when OffsetIsReg is true
20350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Writeback        : 1;
204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
2080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      unsigned RegNum;
2090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    } Shift;
210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
21116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
212146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
213146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
214762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
215762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
216762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
217762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
218762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2208462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2218462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
222762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
224762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
225d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
226762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
227762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
228762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2298d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2300f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
23224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2338d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
234fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
235fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
236fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
237fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
238762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
239762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
240762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
241706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
242706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
243706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
246762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
250a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
251a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
2520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
2530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    case Shifter:
2540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      Shift = o.Shift;
2550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
25816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
260762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
263a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
2658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
2668462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
2678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
2688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
269fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
270fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
271fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
272fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
273fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
274a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
275a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
276a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
278a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
2806aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
2817729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
282a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2845fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
2850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
2860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
28724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
2888d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
2898d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
290cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
291cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
292cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
293cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
294cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
295706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
296706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
297706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
298706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
299706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
300a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
301a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
302a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
304a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
305584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
307584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
308584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3106ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @name Memory Operand Accessors
3116ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @{
312ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ARMII::AddrMode getMemAddrMode() const {
313ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return Mem.AddrMode;
314ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
3156ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemBaseRegNum() const {
3166ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.BaseRegNum;
3176ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3186ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegNum() const {
3196ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3206ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.RegNum;
3216ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3226ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemOffset() const {
3236ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(!Mem.OffsetIsReg && "Invalid access!");
3246ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.Value;
3256ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3266ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegShifted() const {
3276ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3286ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.OffsetRegShifted;
3296ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemShiftAmount() const {
3316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftAmount;
3336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc getMemShiftType() const {
3356ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftType;
3376ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPreindexed() const { return Mem.Preindexed; }
3396ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPostindexed() const { return Mem.Postindexed; }
3406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
3416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemNegative() const { return Mem.Negative; }
3426ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemWriteback() const { return Mem.Writeback; }
3436ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
3446ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @}
3456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
346fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
347fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
349d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3503483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
351b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
3528d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
3530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
3540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
35514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
356706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
35714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
3580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool isShifter() const { return Kind == Shifter; }
359ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool isMemMode2() const {
360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode2)
361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
362ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
363ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg())
364ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return true;
365ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
366ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemNegative() &&
367ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
368ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
369ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
370ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
371ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (!CE) return false;
372ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Value = CE->getValue();
373ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
374ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // The offset must be in the range 0-4095 (imm12).
375ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Value > 4095 || Value < -4095)
376ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
377ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
378ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return true;
379ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
380ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool isMemMode3() const {
381ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode3)
382ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
383ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
384ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
385ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (getMemOffsetRegShifted())
386ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return false; // No shift with offset reg allowed
387ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
388ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
389ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
390ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemNegative() &&
391ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
392ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
393ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
394ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
395ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (!CE) return false;
396ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Value = CE->getValue();
397ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
398ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // The offset must be in the range 0-255 (imm8).
399ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Value > 255 || Value < -255)
400ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
401ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
402ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
403ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
40487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  bool isMemMode5() const {
4054b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
4064b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar        getMemNegative())
40787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
408ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4094b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
410ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
411ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
41287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    // The offset must be a multiple of 4 in the range 0-1020.
41387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    int64_t Value = CE->getValue();
41487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
41587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
416505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  bool isMemMode7() const {
417505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!isMemory() ||
418505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPreindexed() ||
419505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPostindexed() ||
420505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemOffsetIsReg() ||
421505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemNegative() ||
422505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemWriteback())
423505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
424505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
425505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
426505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!CE) return false;
427505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
428505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (CE->getValue())
429505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
430505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
431505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
432505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
433f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeRegThumb() const {
4344b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
435f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
436d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    return true;
437f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
438f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeImmThumb() const {
4394b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
440ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
441ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4424b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
443ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
444ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
445ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    // The offset must be a multiple of 4 in the range 0-124.
446ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint64_t Value = CE->getValue();
447ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    return ((Value & 0x3) == 0 && Value <= 124);
448ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
449584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
450a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
4513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
4523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
45314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
45414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
45514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
45614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
4573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
4583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
4593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
4603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
4613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
4628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
463345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
4648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
46504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
46604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
4678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
469fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
470fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
471fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
472fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
473fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
474fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
475fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
476fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
477fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
478fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
479d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
480d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
481d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
482d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
483d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
484a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
485a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
486a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
487a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4890082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  void addShifterOperands(MCInst &Inst, unsigned N) const {
4900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
4910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
4920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
4930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
4940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
49587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
4967729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
4975fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
4985fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
4997729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
5007729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
50187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
50287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
5030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
5040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5050f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5060f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5070f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
5080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5100f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5113483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
5123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
5133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
5143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
51516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
516706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
517706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
518706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
519706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
520706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
521505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
522505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
523505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
524505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
525505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
5261866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay    (void)CE;
527505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert((CE || CE->getValue() == 0) &&
528505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes           "No offset operand support in mode 7");
529505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
530505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
531ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
532ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(isMemMode2() && "Invalid mode or number of operands!");
533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
536ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg()) {
537ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
538ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
539ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
540ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
541ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      int64_t ShiftAmount = 0;
542ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
543ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (getMemOffsetRegShifted()) {
544ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShOpc = getMemShiftType();
545ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        const MCConstantExpr *CE =
546ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
547ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShiftAmount = CE->getValue();
548ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      }
549ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
550ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
551ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           ShOpc, IdxMode)));
552ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return;
553ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
554ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
555ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
556ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
557ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
558ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
559ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // the difference?
560ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
561ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(CE && "Non-constant mode 2 offset operand!");
562ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Offset = CE->getValue();
563ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
564ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Offset >= 0)
565ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
566ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           Offset, ARM_AM::no_shift, IdxMode)));
567ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    else
568ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
569ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                          -Offset, ARM_AM::no_shift, IdxMode)));
570ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
571ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
572ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
573ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(isMemMode3() && "Invalid mode or number of operands!");
574ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
575ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
576ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
577ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
578ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
579ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
580ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
581ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
582ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                                             IdxMode)));
583ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return;
584ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
585ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
586ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
587ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
588ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
589ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
590ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // the difference?
591ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
592ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(CE && "Non-constant mode 3 offset operand!");
593ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Offset = CE->getValue();
594ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
595ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Offset >= 0)
596ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
597ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           Offset, IdxMode)));
598ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    else
599ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
600ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           -Offset, IdxMode)));
601ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
602ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
60314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
60414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
60516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6064b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6074b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
60892b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
60980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
61080eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // the difference?
6114b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
612d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert(CE && "Non-constant mode 5 offset operand!");
613d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
614d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // The MCInst offset operand doesn't include the low two bits (like
615d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // the instruction encoding).
616d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    int64_t Offset = CE->getValue() / 4;
617d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    if (Offset >= 0)
618d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
619d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             Offset)));
620d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    else
621d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
622d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             -Offset)));
62314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
6243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
625f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
626f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
6274b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6284b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
629f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
630ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
631f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
632f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
6334b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6344b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
635f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(CE && "Non-constant mode offset operand!");
636f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
637ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
638ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
639584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
640584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
641584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
642584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
643584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
644a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
645a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
646a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
647a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
648a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
649fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  virtual void dump(raw_ostream &OS) const;
650b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
6513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
6523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
653345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
654345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
655345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
6563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
657345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
658345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
659fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
660fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
661fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
662fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
663fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
664fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
665fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
666fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
667fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
668fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
669fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
670fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
671fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
672fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
673fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
674fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
675d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
676d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
677d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
678d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
679d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
680d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
681d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
682d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
6833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
6843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
685762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
686762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
687762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
688762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
6893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
690a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
69250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
6933a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
694762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
695762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
696762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
6973a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
698a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
699a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
7000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
7010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
7020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    ARMOperand *Op = new ARMOperand(Shifter);
7030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->Shift.ShiftTy = ShTy;
7040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
7050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
7060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
7070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
7080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
7097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
7105fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
711cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
7120f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
7130f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7140f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    if (ARM::DPRRegClass.contains(Regs.front().first))
7150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
7160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    else if (ARM::SPRRegClass.contains(Regs.front().first))
7170f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
7180f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7190f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
7205fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
7217729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
72224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
723cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
724cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
725cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
7268d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
7278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
7288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
7293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
7303a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
731762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
732762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
733762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
7343a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
735cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
736cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
737ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
738ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               bool OffsetIsReg, const MCExpr *Offset,
739ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               int OffsetRegNum, bool OffsetRegShifted,
7400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               enum ARM_AM::ShiftOpc ShiftType,
7413a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
7423a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
7433a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
744023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((OffsetRegNum == -1 || OffsetIsReg) &&
745023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegNum must imply OffsetIsReg!");
746023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!OffsetRegShifted || OffsetIsReg) &&
747023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegShifted must imply OffsetIsReg!");
748d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert((Offset || OffsetIsReg) &&
749d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar           "Offset must exists unless register offset is used!");
750023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
751023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have shift amount without shifted register offset!");
752023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!Offset || !OffsetIsReg) &&
753023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have expression offset and register offset!");
754023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar
7553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
756ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Op->Mem.AddrMode = AddrMode;
757762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
758762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
7592637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    if (OffsetIsReg)
7602637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.RegNum = OffsetRegNum;
7612637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    else
7622637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.Value = Offset;
763762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
764762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
765762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
766762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
767762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
768762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
769762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
77016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
771762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
772762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
7733a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
774a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
775706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
776706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
777706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
778706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
779706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
780706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
781706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
782706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
783a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
784a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
785a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
786a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
787a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
788a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
789a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
790a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
791584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
792584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
793584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
794584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
795584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
796584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
797584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
798584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
799a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
800a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
801a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
802a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
803fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const {
804fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
805fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
8066a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
807fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
808d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
809d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
810d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
811fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
812fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
813fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
814fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
815fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
816fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
817584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
818584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
819584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
820fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
821fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
822fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
823706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
824706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
825706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
826fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
8276ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
828ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
829ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << " base:" << getMemBaseRegNum();
8306ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg()) {
8316ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:<register " << getMemOffsetRegNum();
8326ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      if (getMemOffsetRegShifted()) {
8336ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-type:" << getMemShiftType();
8346ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-amount:" << *getMemShiftAmount();
8356ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      }
8366ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    } else {
8376ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:" << *getMemOffset();
8386ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    }
8396ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg())
8406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (offset-is-reg)";
8416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPreindexed())
8426ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (pre-indexed)";
8436ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPostindexed())
8446ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (post-indexed)";
8456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemNegative())
8466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (negative)";
8476ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemWriteback())
8486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (writeback)";
8496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
850fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
851a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
852a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
853a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
856a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
857a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
858a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
859a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
860fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
86150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
862fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
8630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  case Shifter:
8640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    OS << "<shifter " << getShiftOpcStr(Shift.ShiftTy) << ">";
8650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
8660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
8670f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
8680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
8698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
8708d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
8715fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
8725fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
8737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
8747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
8757729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
8768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
8778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
8788d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
8798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
8808d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
881fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
882fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
883fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
884fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
885fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
8863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
8883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
8893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
8913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
8933483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
89469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
89569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
896bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  RegNo = TryParseRegister();
897bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
898bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
899bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
900bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
9019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
902e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
903e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
9043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
905e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() {
90618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
907a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
908d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
909a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
910a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
9110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
9120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
9130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
9140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
9150c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
9160c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
9170c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
9180c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
9190c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
9200c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
9210c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
9220c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
92369df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
924b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
925e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
926e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
927d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
9280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// Try to parse a register name.  The token must be an Identifier when called,
9290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// and if it is a register name the token is eaten and the register number is
9300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// returned.  Otherwise return -1.
9310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson///
9320082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::TryParseShiftRegister(
9330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
9340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
9350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
9360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
9370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
9390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
9400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
9410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
9420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
9430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
9440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
9450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
9460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
9470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
9490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return true;
9500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  Parser.Lex(); // Eat shift-type operand;
9520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  int RegNum = TryParseRegister();
9530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (RegNum == -1)
9540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Error(Parser.getTok().getLoc(), "register expected");
9550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  Operands.push_back(ARMOperand::CreateReg(RegNum,S, Parser.getTok().getLoc()));
9570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  Operands.push_back(ARMOperand::CreateShifter(ShiftTy,
9580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
9590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  return false;
9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
9620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
96450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
96550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
96650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
967e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
968e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
969e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
97050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
97150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
972e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
973e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int RegNo = TryParseRegister();
974e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
97550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
976d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
97750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
978a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
979e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
980e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
98150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
98250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
983e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
98499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
98599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
98650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
987a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
988a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
989fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
990fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
991fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
992fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
993e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
994e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
995e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
996e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
997e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
998fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
999e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1000e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1001e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1002e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1003e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1004e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1005e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1006e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1007e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1008e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1009e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1010e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1011e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1012e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1013e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1014e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1015fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1016e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1017e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1018e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1019e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1020e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1021e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1022e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1023e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1024e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1025e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1026e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1027e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1028e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1029e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1030e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1031e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1032f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1035f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1036f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1037e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1038e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1039e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1040e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1041fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1042e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1043f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1044e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1045e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1046fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1047f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1048fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1049fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1050f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1051fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1052fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1053f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1054f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1055fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1056fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1057fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1058fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1059fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1060fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1061f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1062fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1064fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1065f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1066e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1067e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1068c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1069c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
107050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
107150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
107218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1073a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1074e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
107516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
10767729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
10777729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
10785fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1079d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
10807729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1081e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
10827729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1083d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
108418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1085d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1086c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1087c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
108850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1089c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1090e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
10911d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling    int RegNum = TryParseRegister();
1092c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1093c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
109450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1095c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1096d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1097e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1098e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1099e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1100e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1101e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1102e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1103e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1104e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1105e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1106e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1107e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
11087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
11097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1110e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1111e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
111218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1113c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1114c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
111550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1116c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1117d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1118e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1119e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
112003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1121e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
11225fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1123e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1124e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
11257caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
11268e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
11278e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
11287caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
11297caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
11307caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1131e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
11327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
11337caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1134e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
11358e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1136e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
113750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1138e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1139e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
11408e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1141e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1142e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1143e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
11448e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
11458e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1146e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1147e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
114850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
114950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1150d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1151d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1152f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1153f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1154f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1155706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1156706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1157706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1158706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1159706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1160706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1161706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1162706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1163706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1164706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1165706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1166706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1168706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1169706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1170706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1171706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1172f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1173706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1174706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1175706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1176f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1177706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
11798bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1180a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1181a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1182a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1183a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1184a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1185a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1186a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1187a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1188a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1190a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1193a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1194a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1195a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1196a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1201a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1202a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1205a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1206584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1207584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1208584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1209584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1210584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1212584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1213584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1214584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1215584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1216584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1217584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1218584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1219584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef SpecReg = Mask.slice(Start, Next);
1220584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1221584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1222584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1223584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1224584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1225584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1226584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1227584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1228584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1229584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1230584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvq",  0x8) // same as CPSR_c
1231584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1232584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1233584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1234584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
12354b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1236584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1237584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1238584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1239584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
12404b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1241584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
1242584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1244584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1245584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1246584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1247584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1248584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1249584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1250584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1251584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1252584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1253584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1254584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1255584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1256584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1257584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1258584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1259584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1260584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1261584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1262584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1263584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1264584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1265584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1266584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1267584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1268584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1269584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1271a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1272ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1273ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1274ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1275e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1276ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1277ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode2))
1278ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return MatchOperand_NoMatch;
1279ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1280ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return MatchOperand_Success;
1281ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1282ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1283ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1284ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1285ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1286ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1287ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1288ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode3))
1289ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1290ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1291ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return MatchOperand_Success;
1292ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1293ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1294ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1295ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1296ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1297ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1298ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1299ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1300ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1301ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1302ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1303ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1304ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1305ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1306ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1307ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1308ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1309ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1310ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1311ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1312ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1313ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1314ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1315ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1316ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1317ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1318ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1319ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1320ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1321ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1322ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1323ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1324ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1325ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1326ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1327ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1328ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1329ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1330ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1331ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1332ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1333ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1334ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1335ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1336ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1337ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1338ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1339ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1340ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1341ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1342ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1343ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1344ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1345ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1346ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1347ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1348ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1349ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1350ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1351ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1352ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1354e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
13559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
135650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling///
13579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
13589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
135950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
1360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1362762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
136318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
1364a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
1365762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
1366b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
1367a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
136818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
1369550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1370550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
137150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1372550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1373e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int BaseRegNum = TryParseRegister();
1374e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (BaseRegNum == -1) {
1375550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
137650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1377550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
13790571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
13800571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
13810571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
13820571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    return true;
13830571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
1384a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
1385a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
1386a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
1387a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
1388a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
138905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  ARMOperand *WBOp = 0;
139005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  int OffsetRegNum = -1;
139105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  bool OffsetRegShifted = false;
13920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
139305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *ShiftAmount = 0;
139405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *Offset = 0;
1395a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
13969c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
13979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
1398a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
1399a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
1400b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
140105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1402550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1403550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
140450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
140518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
1406550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
1407550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
140850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1409550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
1410762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
1411b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1412a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
141318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
1414a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
1415ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      // None of addrmode3 instruction uses "!"
1416ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode3)
1417ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return true;
1418ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
141950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
142050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                     ExclaimTok.getLoc());
1421a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
1422b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
1423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode2)
1425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        Preindexed = false;
1426a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
14270571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  } else {
14280571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    // The "[Rn" we have so far was not followed by a comma.
14290571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
143080eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // If there's anything other than the right brace, this is a post indexing
143180eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // addressing form.
1432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
1433b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1434a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
143518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
143603f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1437e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
143880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Postindexed = true;
143980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Writeback = true;
144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1441550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
1442550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
144350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1444550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
144550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1446b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
144750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1448550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
144916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1450550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
145150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
145305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  }
1454e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
145505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  // Force Offset to exist if used.
145605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (!OffsetIsReg) {
145705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    if (!Offset)
145805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar      Offset = MCConstantExpr::Create(0, getContext());
1459ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  } else {
1460ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1461ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Error(E, "shift amount not supported");
1462ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
1463ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
1464a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
146505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1466ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1467ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Offset, OffsetRegNum, OffsetRegShifted,
1468ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     ShiftType, ShiftAmount, Preindexed,
1469ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Postindexed, Negative, Writeback, S, E));
147005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (WBOp)
147105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    Operands.push_back(WBOp);
147205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
147305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  return false;
1474a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1475a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
14779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
14789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
14799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
14809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
14819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
14829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
14839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1484762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
14850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                        enum ARM_AM::ShiftOpc &ShiftType,
14869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
14879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
14889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
1489762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
1490762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
14919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
14929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
14939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
14949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
149518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
1496762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
14979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
1498b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
14999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
15009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
1501b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
15029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
15039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
150418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
15059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
1506e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    SMLoc CurLoc = OffsetRegTok.getLoc();
1507e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    OffsetRegNum = TryParseRegister();
1508e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    if (OffsetRegNum != -1) {
1509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
1510e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner      E = CurLoc;
1511762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
15129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
1513d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
151412f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling  // If we parsed a register as the offset then there can be a shift after that.
15159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
15169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
151718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
15189c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
1519b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
15209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
152118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
1522762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
15233472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
15249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
15259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
15269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
15279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
15289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
152918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
15309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
15319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
153216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1533b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
15349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
15359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
15369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
1537762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
15389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
15399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
15409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
15419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
1542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
1543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
1544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
1545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
15460082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
15470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                              const MCExpr *&ShiftAmount, SMLoc &E) {
154818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1549a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
1550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
155138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
1552a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
15530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
1554a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
15550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
1556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
15570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
1558a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
15590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
1560a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
15610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
1562a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
1563a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
1564b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
1565a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
15670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (St == ARM_AM::rrx)
15689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
1569a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
157118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
15729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
15739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
1574b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
15759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
15769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
15779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
1578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1579a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
1580a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1581a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
15839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
1584e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1585fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
1586762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
1587fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1588fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
1589fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
1590f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1591f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
1592fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
1593f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1594f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
1595f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
1596f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
1597f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
1598fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1599a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
1600146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
1601146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
160250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
160367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Identifier:
160450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    if (!TryParseRegisterWithWriteBack(Operands))
160550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
16060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    if (!TryParseShiftRegister(Operands))
16070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
16080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1609e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1610e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
1611e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
161267b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
161367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
1614515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
1615515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
1616515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
1617762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1618515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
161950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1620762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
162150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
162250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
162350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
1624a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
162550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseMemory(Operands);
1626d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
162750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseRegisterList(Operands);
1628d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
1629079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
1630079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1631762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1632b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
1633515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
1634515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
163550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1636762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
163750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
163850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
16399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
16409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
16417597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
16427597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
16437597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
16449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (ParsePrefix(RefKind))
16459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
16469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16477597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
16487597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
16499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
16509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16517597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
16527597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
16539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
16547597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
16559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
16569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
1657a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1658a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1659a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
16607597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
16617597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
16627597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
16637597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
16649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
16668a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
16679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
16689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
16709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
16719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
16729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
16739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
16759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
16767597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
16779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
16787597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
16799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
16809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
16819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
16829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
16839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
16849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
16869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
16879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
16889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
16899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
16909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
16919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
16929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
16939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
16949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
16959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
16969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
16979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
16989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
16999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
17009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
17029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
17039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
17049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
17059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
17069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
17089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
17099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
17119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
17129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
17149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
17179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
17189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
17209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
17219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
17229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
17239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
17249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
17259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
17279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
17319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
17329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
17339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
1734352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
1735352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
1736352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
1737badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
1738a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic,
1739a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &PredicationCode,
1740a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               bool &CarrySetting,
1741a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &ProcessorIMod) {
1742352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
1743352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
1744a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
1745352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1746badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
1747352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
1748352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
17498ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar  if (Mnemonic == "teq" || Mnemonic == "vceq" ||
17508ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "movs" ||
17518ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "svc" ||
17528ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
17538ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vmls" || Mnemonic == "vnmls") ||
17548ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacge" || Mnemonic == "vcge" ||
17558ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vclt" ||
17568ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacgt" || Mnemonic == "vcgt" ||
17578ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vcle" ||
17588ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
17598ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
17608ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vqdmlal"))
1761352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
1762badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1763352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // First, split out any predication code.
1764badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
1765345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("eq", ARMCC::EQ)
1766345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ne", ARMCC::NE)
1767345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hs", ARMCC::HS)
1768345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lo", ARMCC::LO)
1769345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("mi", ARMCC::MI)
1770345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("pl", ARMCC::PL)
1771345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vs", ARMCC::VS)
1772345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vc", ARMCC::VC)
1773345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hi", ARMCC::HI)
1774345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ls", ARMCC::LS)
1775345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ge", ARMCC::GE)
1776345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lt", ARMCC::LT)
1777345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("gt", ARMCC::GT)
1778345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("le", ARMCC::LE)
1779345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("al", ARMCC::AL)
1780345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Default(~0U);
1781badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  if (CC != ~0U) {
1782badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
1783352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    PredicationCode = CC;
178452925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
1785345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1786352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
1787352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
1788352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
1789352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
1790352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
1791352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
1792352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
1793352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
1794352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
1795352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
1796352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
1797352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1798a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
1799a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
1800a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
1801a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
1802a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
1803a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
1804a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
1805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
1806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
1807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
1808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
1809a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
1810a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
1811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1812a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1813352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
1814352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
18153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
18163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
18173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
18183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
18193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
1820fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
1821fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
1822fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
1823fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes  bool isThumb = TM.getSubtarget<ARMSubtarget>().isThumb();
1824fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes
1825eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
1826eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
1827eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
1828eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
1829eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mov" ||
1830eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
1831eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
1832eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "mvn") {
1833eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
1834eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
1835eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
1836eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
18373771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
1838eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
1839eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
1840eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
1841eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
1842e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes      Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
1843a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
18443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
18453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
18463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
18473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
1848fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
1849fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes  if (isThumb)
1850fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
18518dd37f7b7dca7907f9f070dc96359f242e102163Bruno Cardoso Lopes        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
1852fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
1853badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
1854badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1855badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
1856badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
1857badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1858badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
1859badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
1860badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  StringRef Head = Name.slice(Start, Next);
1861badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1862352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
1863352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
1864a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
1865352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
1866a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Head = SplitMnemonic(Head, PredicationCode, CarrySetting,
1867a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                       ProcessorIMod);
1868badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
18693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
18709717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
18713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
18723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
18733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
18743771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
18753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
18763771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
18773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
18783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
18793771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode);
18803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
18813771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
18823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
18833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
18843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
18853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
18863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptCarrySet) {
18873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
18883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
18893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
18903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a carry set, but the user wrote one (or
18913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // misspelled another mnemonic).
18923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
18933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
18943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
18953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
18963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
18973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
18983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
18993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
19003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
19013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a predication code, but the user wrote
19023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // one (or misspelled another mnemonic).
19033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
19043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
1905badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
1906345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1907a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
1908a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
1909a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
1910a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
1911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
1912a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
1913a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
1914a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
1915a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
1917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1918a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1919345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
19205747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
19215747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
19225747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
1923a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
1924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1925a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
19265747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
19275747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
19285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
19295747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1930a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
1931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (ParseOperand(Operands, Head)) {
1932cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
1933cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
1934cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
1935a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1936a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
1937b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
1938a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1939a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
1940fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      if (ParseOperand(Operands, Head)) {
1941cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
1942cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
1943cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
1944a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
1945a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
194616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1947cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1948cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
194934e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
1950cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
1951146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
195234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
19539898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
1954ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
1955ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1956fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
1957fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
1958fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1959fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
1960fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
1961fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
1962193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResultTy MatchResult, MatchResult2;
1963193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
1964193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  if (MatchResult != Match_Success) {
1965193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_InvalidOperand it might be some arithmetic instruction
1966193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that does not update the condition codes.  So try adding a CCOut operand
1967193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // with a value of reg0.
1968193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    if (MatchResult == Match_InvalidOperand) {
1969193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      Operands.insert(Operands.begin() + 1,
1970193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                      ARMOperand::CreateCCOut(0,
1971193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                                  ((ARMOperand*)Operands[0])->getStartLoc()));
1972193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
1973193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (MatchResult2 == Match_Success)
1974193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult = Match_Success;
197544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      else {
197644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
1977193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.erase(Operands.begin() + 1);
197844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete CCOut;
197944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      }
1980193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
1981193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_MnemonicFail it might be some arithmetic instruction
1982193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that updates the condition codes if it ends in 's'.  So see if the
1983193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
1984193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // operand with a value of CPSR.
1985193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    else if(MatchResult == Match_MnemonicFail) {
1986193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      // Get the instruction mnemonic, which is the first token.
1987193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
1988193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
1989193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        // removed the 's' from the mnemonic for matching.
1990193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
1991193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
199244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
199344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.erase(Operands.begin());
199444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete OldMnemonic;
199544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.insert(Operands.begin(),
1996193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateToken(MnemonicNoS, NameLoc));
1997193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.insert(Operands.begin() + 1,
1998193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
1999193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2000193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        if (MatchResult2 == Match_Success)
2001193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby          MatchResult = Match_Success;
2002193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        else {
200344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
200444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin());
200544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete OldMnemonic;
200644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.insert(Operands.begin(),
2007193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                          ARMOperand::CreateToken(Mnemonic, NameLoc));
200844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
200944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin() + 1);
201044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete CCOut;
2011193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        }
2012193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      }
2013193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2014193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  }
2015193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2016e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2017fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2018fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2019e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2020e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2021e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2022e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2023e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2024e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2025e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2026e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
202716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2028e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2029e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2030e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
203116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2032e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2033e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2034e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2035e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2036b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2037b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2038fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
203916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2040c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2041146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2042fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2043fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
2044515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
2045ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2046ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2047ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
2048ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
2049515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
2050515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
2051515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
2052515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2053515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
2054515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
2055515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
2056515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
2057ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2058ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2059ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2060ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
2061ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
2062ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2063ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2064ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2065ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2066ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2067ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2068ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2069aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2070ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2071ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2072ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
207316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2074ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2075ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2076ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2077b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2078ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2079ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2080ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2081b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2082ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2083ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2084ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2085515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
2086515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
2087515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2088515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2089515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2090b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2091515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2092515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2093515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2094515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2095515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2096515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2097515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2098515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
2099515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
2100515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
210118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2102515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
210383c4018fcca18fe9c281c3943fc58a17621636c4Jim Grosbach    return Error(L, "unexpected token in .thumb_func directive");
2104642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  StringRef Name = Tok.getString();
2105b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Consume the identifier token.
2106515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2107515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2108b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2109515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2110642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2111642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2112642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2113515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2114515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2115515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2116515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
2117515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
2118515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
211918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2120515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2121515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
212238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
212358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2124b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
212558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
21269e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2127515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2128515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2129515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2130515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
213118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2132b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2133515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2134515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2135515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2136515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2137515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2138515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2139515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
2140515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
2141515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
214218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2143515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2144515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
214518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
214658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2147b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
214858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2149b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2150515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2151515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2152515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
215418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2155b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2157fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  // FIXME: We need to be able switch subtargets at this point so that
2158fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  // MatchInstructionImpl() will work when it gets the AvailableFeatures which
2159fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  // includes Feature_IsThumb or not to match the right instructions.  This is
2160fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  // blocked on the FIXME in llvm-mc.cpp when creating the TargetMachine.
2161fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  if (Val == 16){
2162fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby    assert(TM.getSubtarget<ARMSubtarget>().isThumb() &&
2163fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby	   "switching between arm/thumb not yet suppported via .code 16)");
21642a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2165fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  }
2166fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby  else{
2167fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby    assert(!TM.getSubtarget<ARMSubtarget>().isThumb() &&
2168fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby           "switching between thumb/arm not yet suppported via .code 32)");
21692a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2170fef9ff492206330ff0a5b94cec5ac1455b28df88Kevin Enderby   }
21712a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2172515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2173515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2174515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
217590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
217690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
21779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2178ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
2179ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2180ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
218190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2182ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
21833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
21840692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
21850692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
21863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2187