ARMAsmParser.cpp revision eac0796542d098caa371856d545faa6cdab5aad3
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h"
1192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling#include "ARMAddressingModes.h"
127597212abced110723f2fee985a7d60557c092ecEvan Cheng#include "ARMMCExpr.h"
13b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h"
143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
16c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
17c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
19642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h"
25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2875ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
34ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "ARMGenSubtargetInfo.inc"
36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
53e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int TryParseRegister();
54bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
5550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
5619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
5750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
58ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
59ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   ARMII::AddrMode AddrMode);
60fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
617597212abced110723f2fee985a7d60557c092ecEvan Cheng  bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
65a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                            enum ARM_AM::ShiftOpc &ShiftType,
699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
72762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
73762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool ParseShift(enum ARM_AM::ShiftOpc &St,
750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                  const MCExpr *&ShiftAmount, SMLoc &E);
76ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
79515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
80515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
827036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
837c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
84fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                               MCStreamer &Out);
85fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes  void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
86fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
8716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
89ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
93ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
94ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
9532869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
96ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
97ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
9832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
99ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
101a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1023483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1030692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1040692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
107a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocNumOperand(
109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocRegOperand(
111f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseMemBarrierOptOperand(
1138bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  OperandMatchResultTy tryParseProcIFlagsOperand(
1158bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
116584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  OperandMatchResultTy tryParseMSRMaskOperand(
1178bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode2Operand(
119ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
120ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode3Operand(
121ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
123ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
124ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
125ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
128ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
129ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
130ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
131ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
132f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach
133ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
134ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
135ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    : TargetAsmParser(), STI(_STI), Parser(_Parser) {
136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
13732869205052430f45d598fba25ab878d8b29da2dEvan Cheng
138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
139ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
141ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
14238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1439898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
144ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
145ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
14616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
14716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1483a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
150a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
151a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
152146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
153762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1548462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
155d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
156fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
157fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
158cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
159706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
161584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
162a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1648d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1660f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
167e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
1680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Shifter,
1698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
171a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
17324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
174a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
175a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
176a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1808462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
181706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
182706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
183706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
184706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
185fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
186fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
188fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
189a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
190a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
191a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
192a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
193584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
194584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
195584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
196584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
197a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
198a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
199a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
200a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
201a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
202a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
203a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
204a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2058155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
206cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
207cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
20816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2096a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
211ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARMII::AddrMode AddrMode;
212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2132637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      union {
2142637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
2152637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
2162637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      } Offset;
217146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
2180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
219146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
22050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Preindexed       : 1;
22150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Postindexed      : 1;
22250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned OffsetIsReg      : 1;
22350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Negative         : 1; // only used when OffsetIsReg is true
22450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Writeback        : 1;
225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
2300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    } Shift;
231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
233e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } ShiftedReg;
237a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
23816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
239146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
240146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
241762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
242762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
243762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
244762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
245762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2468462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2478462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
249762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2508462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
251762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
252d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2568d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
25924d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2608d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
261fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
262fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
263fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
264fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
268706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
269706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
270706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
271762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
272762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
273762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
277a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
278a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
2790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
2800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    case Shifter:
2810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      Shift = o.Shift;
2820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
283e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
284e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftedReg = o.ShiftedReg;
285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
28816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
291762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
292762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
2958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
2968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
2978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
2988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
299fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
300fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
301fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
302fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
303fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
304a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
305a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
306a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3106aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
312a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3150f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3160f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
31724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3188d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3198d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
320cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
321cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
322cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
323cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
324cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
325706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
326706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
327706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
328706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
329706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
337584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
338584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
339584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3406ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @name Memory Operand Accessors
3416ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @{
342ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ARMII::AddrMode getMemAddrMode() const {
343ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return Mem.AddrMode;
344ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
3456ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemBaseRegNum() const {
3466ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.BaseRegNum;
3476ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegNum() const {
3496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3506ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.RegNum;
3516ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3526ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemOffset() const {
3536ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(!Mem.OffsetIsReg && "Invalid access!");
3546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.Value;
3556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegShifted() const {
3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.OffsetRegShifted;
3596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemShiftAmount() const {
3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftAmount;
3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc getMemShiftType() const {
3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftType;
3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPreindexed() const { return Mem.Preindexed; }
3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPostindexed() const { return Mem.Postindexed; }
3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemNegative() const { return Mem.Negative; }
3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemWriteback() const { return Mem.Writeback; }
3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @}
3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
376fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
379d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
3816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
3826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
3836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
3846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
3866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
3876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
3886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
38983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
39083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
39183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
39283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
39383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
39483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
39583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
39683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
39783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
39883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
39983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
40083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
40183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
40283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
40383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
40483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
405fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
406fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
407fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
408fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
409fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
410fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
411fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
412fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
4136b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
4146b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4156b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4166b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4176b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4186b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
4206b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
421b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
4228d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
4230f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
4240f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
42514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
426706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
42714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
4280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool isShifter() const { return Kind == Shifter; }
429e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  bool isShiftedReg() const { return Kind == ShiftedRegister; }
430ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool isMemMode2() const {
431ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode2)
432ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
433ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg())
435ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return true;
436ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
437ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemNegative() &&
438ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
439ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
440ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
441ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
442ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (!CE) return false;
443ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Value = CE->getValue();
444ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
445ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // The offset must be in the range 0-4095 (imm12).
446ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Value > 4095 || Value < -4095)
447ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
448ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
449ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return true;
450ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
451ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool isMemMode3() const {
452ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode3)
453ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
454ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
455ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
456ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (getMemOffsetRegShifted())
457ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return false; // No shift with offset reg allowed
458ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
459ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
460ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
461ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemNegative() &&
462ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
463ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
464ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
465ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
466ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (!CE) return false;
467ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Value = CE->getValue();
468ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
469ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // The offset must be in the range 0-255 (imm8).
470ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Value > 255 || Value < -255)
471ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
472ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
473ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
474ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
47587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  bool isMemMode5() const {
4764b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
4774b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar        getMemNegative())
47887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
479ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4804b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
481ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
482ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
48387f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    // The offset must be a multiple of 4 in the range 0-1020.
48487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    int64_t Value = CE->getValue();
48587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
48687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
487505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  bool isMemMode7() const {
488505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!isMemory() ||
489505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPreindexed() ||
490505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPostindexed() ||
491505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemOffsetIsReg() ||
492505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemNegative() ||
493505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemWriteback())
494505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
495505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
496505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
497505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!CE) return false;
498505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
499505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (CE->getValue())
500505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
501505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
502505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
503505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
504f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeRegThumb() const {
5054b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
506f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
507d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    return true;
508f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
509f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeImmThumb() const {
5104b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
511ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
512ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
5134b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
514ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
515ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
516ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    // The offset must be a multiple of 4 in the range 0-124.
517ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint64_t Value = CE->getValue();
518ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    return ((Value & 0x3) == 0 && Value <= 124);
519ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
520584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
5223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
52414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
52514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
52614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
52714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
5283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
5293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
5303483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
5313483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
5323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5338462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
534345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
5358462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
53604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
53704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
5388462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
5398462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
540fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
541fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
542fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
543fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
544fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
545fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
546fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
547fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
548fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
549fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
550d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
551d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
552d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
553d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
554d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
555a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
557a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
558a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
559a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
560e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
561e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
562e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
563e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert((ShiftedReg.ShiftReg == 0 ||
564e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach            ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) &&
565e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach           "Invalid shifted register operand!");
566e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
567e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
568e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
569e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
570e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
571e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
5720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  void addShifterOperands(MCInst &Inst, unsigned N) const {
5730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
5740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
5750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
5760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
5770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
57887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
5797729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
5805fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
5815fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
5827729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
5837729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
58487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
58587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
5860f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
5870f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5890f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5900f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
5910f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5920f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5930f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5943483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
5956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
5966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
5976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
5986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
5996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
6006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
60483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
60583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
60683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
60783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
60883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
60983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
61083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
61183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
61283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
61383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
614fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
615fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
616fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
617fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
618fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
6196b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
6203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
6213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
6223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
62316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
624706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
625706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
626706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
627706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
628706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
629505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
630505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
631505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
632505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
633505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
6341866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay    (void)CE;
635505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert((CE || CE->getValue() == 0) &&
636505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes           "No offset operand support in mode 7");
637505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
638505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
639ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
640ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(isMemMode2() && "Invalid mode or number of operands!");
641ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
642ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
643ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
644ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg()) {
645ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
646ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
647ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
648ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
649ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      int64_t ShiftAmount = 0;
650ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
651ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (getMemOffsetRegShifted()) {
652ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShOpc = getMemShiftType();
653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        const MCConstantExpr *CE =
654ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
655ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShiftAmount = CE->getValue();
656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      }
657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
659ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           ShOpc, IdxMode)));
660ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return;
661ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
662ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
663ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
664ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
665ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
666ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
667ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // the difference?
668ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
669ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(CE && "Non-constant mode 2 offset operand!");
670ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Offset = CE->getValue();
671ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
672ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Offset >= 0)
673ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
674ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           Offset, ARM_AM::no_shift, IdxMode)));
675ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    else
676ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
677ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                          -Offset, ARM_AM::no_shift, IdxMode)));
678ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
679ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
680ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
681ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(isMemMode3() && "Invalid mode or number of operands!");
682ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
683ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
684ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
685ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
686ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
687ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
688ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
689ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
690ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                                             IdxMode)));
691ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return;
692ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
693ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
694ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
695ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
696ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
697ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
698ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // the difference?
699ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
700ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(CE && "Non-constant mode 3 offset operand!");
701ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Offset = CE->getValue();
702ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
703ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Offset >= 0)
704ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
705ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           Offset, IdxMode)));
706ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    else
707ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
708ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           -Offset, IdxMode)));
709ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
710ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
71114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
71214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
71316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7144b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
7154b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
71692b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
71780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
71880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // the difference?
7194b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
720d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert(CE && "Non-constant mode 5 offset operand!");
721d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
722d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // The MCInst offset operand doesn't include the low two bits (like
723d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // the instruction encoding).
724d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    int64_t Offset = CE->getValue() / 4;
725d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    if (Offset >= 0)
726d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
727d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             Offset)));
728d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    else
729d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
730d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             -Offset)));
73114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
7323483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
733f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
734f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
7354b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
7364b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
737f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
738ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
739f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
740f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
7414b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
7424b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
743f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(CE && "Non-constant mode offset operand!");
744f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
745ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
746ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
747584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
748584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
749584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
750584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
751584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
752a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
753a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
754a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
755a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
756a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
757b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
758b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
7593a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
7603a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
761345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
762345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
763345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
7643a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
765345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
766345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
767fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
768fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
769fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
770fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
771fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
772fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
773fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
774fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
775fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
776fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
777fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
778fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
779fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
780fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
781fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
782fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
783d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
784d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
785d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
786d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
787d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
788d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
789d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
790d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
7913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
7923a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
793762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
794762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
795762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
796762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
7973a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
798a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
799a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
80050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
8013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
802762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
803762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
804762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8053a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
806a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
807a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
808e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
809e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
810e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
811e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
812e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
813e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
814e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftTy = ShTy;
815e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.SrcReg = SrcReg;
816e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftReg = ShiftReg;
817e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftImm = ShiftImm;
818e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
819e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
820e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
821e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
822e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
8230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
8240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
8250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    ARMOperand *Op = new ARMOperand(Shifter);
8260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->Shift.ShiftTy = ShTy;
8270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
8280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
8290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
8300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
8310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
8327729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
8335fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
834cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
8350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
8360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
8370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    if (ARM::DPRRegClass.contains(Regs.front().first))
8380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
8390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    else if (ARM::SPRRegClass.contains(Regs.front().first))
8400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
8410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
8420f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
8435fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
8447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
84524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
846cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
847cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
848cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
8498d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
8508d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
8518d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
8523a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
8533a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
854762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
855762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
856762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
858cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
859cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
860ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
861ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               bool OffsetIsReg, const MCExpr *Offset,
862ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               int OffsetRegNum, bool OffsetRegShifted,
8630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               enum ARM_AM::ShiftOpc ShiftType,
8643a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
8653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
8663a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
867023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((OffsetRegNum == -1 || OffsetIsReg) &&
868023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegNum must imply OffsetIsReg!");
869023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!OffsetRegShifted || OffsetIsReg) &&
870023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegShifted must imply OffsetIsReg!");
871d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert((Offset || OffsetIsReg) &&
872d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar           "Offset must exists unless register offset is used!");
873023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
874023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have shift amount without shifted register offset!");
875023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!Offset || !OffsetIsReg) &&
876023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have expression offset and register offset!");
877023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar
8783a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
879ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Op->Mem.AddrMode = AddrMode;
880762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
881762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
8822637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    if (OffsetIsReg)
8832637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.RegNum = OffsetRegNum;
8842637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    else
8852637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.Value = Offset;
886762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
887762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
888762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
889762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
890762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
891762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
892762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
89316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
894762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
895762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8963a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
897a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
898706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
899706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
900706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
901706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
902706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
903706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
904706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
905706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
906a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
907a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
908a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
909a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
910a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
912a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
913a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
914584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
915584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
916584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
917584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
918584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
919584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
920584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
921584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
922a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
923a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
925a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
926b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
927fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
928fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
9296a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
930fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
931d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
932d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
933d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
934fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
935fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
936fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
937fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
938fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
939fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
940584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
941584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
942584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
943fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
944fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
945fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
946706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
947706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
948706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
949fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
9506ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
951ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
952ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << " base:" << getMemBaseRegNum();
9536ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg()) {
9546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:<register " << getMemOffsetRegNum();
9556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      if (getMemOffsetRegShifted()) {
9566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-type:" << getMemShiftType();
9576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-amount:" << *getMemShiftAmount();
9586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      }
9596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    } else {
9606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:" << *getMemOffset();
9616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    }
9626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg())
9636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (offset-is-reg)";
9646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPreindexed())
9656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (pre-indexed)";
9666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPostindexed())
9676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (post-indexed)";
9686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemNegative())
9696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (negative)";
9706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemWriteback())
9716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (writeback)";
9726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
973fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
974a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
975a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
976a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
977a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
979a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
980a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
981a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
982a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
983fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
98450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
985fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
9860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  case Shifter:
987e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
988e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
989e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
990e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    OS << "<so_reg"
991e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ShiftedReg.SrcReg
992e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
993e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ", " << ShiftedReg.ShiftReg << ", "
994e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
995e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
9960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
9970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
9980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
9990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
10008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
10018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
10025fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
10035fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
10047729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
10057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
10067729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
10078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
10088d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
10098d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
10108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
10118d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1012fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1013fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1014fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1015fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1016fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
10173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
10193483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
10203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10213483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
10223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
10233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
10243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
102569df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
102669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
1027bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  RegNo = TryParseRegister();
1028bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1029bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1030bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1031bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
10329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1033e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1034e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
10353a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
1036e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() {
103718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1038a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1039d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1040a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1041a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
10420c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
10430c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
10440c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
10450c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
10460c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
10470c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
10480c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
10490c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
10500c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
10510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
10520c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
10530c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
105469df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1055b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1056e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1057e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1058d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
105919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
106019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
106119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
106219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
106319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
106419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbachint ARMAsmParser::TryParseShiftRegister(
10650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
10660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
10670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
10680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
10690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
10710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
10720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
10730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
10740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
10750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
10760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
10770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
10780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
10790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
108119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
10820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1083e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1084e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1085e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1088eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1090e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1091e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1092e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1093e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1094e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1095e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1096e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1097e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1098e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1099e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1100e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1101e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1102e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1103e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1104e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
110519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
110619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
110719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
110819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1109e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1110e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
111119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
111219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
111319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
111419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1115e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1116e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1117e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1118e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1119e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1120e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1121e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
112219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
112319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1124e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1125e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
1126e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftReg = TryParseRegister();
1127e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
112819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
112919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
113019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
113119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
113219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
113319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1134e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
113519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
113619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1137e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1138e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1139e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1140e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                                       ShiftReg, Imm,
11410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
11420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
114319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
11440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
11450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
11460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
114750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
114850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
114950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1150e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1151e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1152e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
115350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
115450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1155e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
1156e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int RegNo = TryParseRegister();
1157e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
115850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1159d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
116050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1161a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1162e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1163e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
116450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
116550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1166e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
116799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
116899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
116950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1171a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1172fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1173fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1174fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1175fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1176e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1177e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1178e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1179e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1180e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1181fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1182e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1183e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1184e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1185e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1186e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1187e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1188e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1189e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1190e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1191e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1192e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1193e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1194e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1195e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1196e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1197e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1199e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1203e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1204e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1205e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1206e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1207e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1208e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1209e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1210e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1211e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1212e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1213e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1214e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1215f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1216fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1217fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1218f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1219f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1220e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1221e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1222e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1223e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1224fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1225e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1226f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1227e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1228e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1229fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1230f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1231fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1232fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1233f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1234fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1235fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1236f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1237f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1238fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1239fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1240fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1241fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1242fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1243fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1244f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1245fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1246fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1247fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1248f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1249e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1250e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1251c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1252c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
125350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
125450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
125518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1256a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1257e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
125816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
12597729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
12607729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
12615fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1262d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
12637729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1264e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
12657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1266d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
126718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1268d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1269c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1270c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
127150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1272c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1273e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12741d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling    int RegNum = TryParseRegister();
1275c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1276c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
127750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1278c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1279d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1280e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1281e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1282e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1283e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1284e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1285e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1286e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1287e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1288e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1289e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1290e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
12917729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
12927729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1293e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1294e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
129518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1296c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1297c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
129850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1299c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1300d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1301e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1302e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
130303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1304e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
13055fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1306e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1307e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
13087caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
13098e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
13108e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
13117caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
13127caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
13137caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1314e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
13157729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
13167caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1317e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
13188e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1319e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
132050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1321e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1322e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
13238e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1324e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1325e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1326e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
13278e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
13288e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1329e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1330e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
133150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
133250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1333d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1334d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1335f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1336f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1337f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1338706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1339706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1340706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1341706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1342706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1343706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1344706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1345706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1346032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
1347706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1348032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
1349706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1350706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1351032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
1352706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1353032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
1354706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1355706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1356706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1357706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1358706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1359f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1360706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1361706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1362706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1363f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1364706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1365706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
13668bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1367a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1368a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1370a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1371a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1372a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1373a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1374a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1375a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1376a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1377a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1378a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1379a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1380a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1381a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1382a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1383a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1384a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1385a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1386a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1387a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1388a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1389a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1390a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1391a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1392a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1393584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1394584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1395584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1396584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1397584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1398584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1399584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1400584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1401584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1402584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1403584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1404584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1406584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef SpecReg = Mask.slice(Start, Next);
1407584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1408584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1409584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1410584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1411584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1412584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1413584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1414584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1415584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1416584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1417584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvq",  0x8) // same as CPSR_c
1418584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1419584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1420584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1421584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
14224b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1423584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1424584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1425584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1426584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
14274b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1428584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
142956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
143056926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1431584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1432584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1433584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1434584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1435584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1436584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1437584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1438584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1439584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1440584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1441584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1442584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1443584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1444584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1445584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1446584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1447584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1448584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1449584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1450584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1451584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1452584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1453584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1454584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1455584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1456584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1457584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1458584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1459a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1460a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1461ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1462ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1463ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1464e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1465ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1466ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode2))
1467ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return MatchOperand_NoMatch;
1468ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1469ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return MatchOperand_Success;
1470ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1471ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1472ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1473ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1474ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1475ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1476ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1477ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode3))
1478ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1479ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1480ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return MatchOperand_Success;
1481ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1482ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1483ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1484ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1485ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1486ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1487ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1488ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1489ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1490ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1491ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1492ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1493ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1494ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1495ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1496ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1497ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1498ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1499ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1500ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1501ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1502ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1503ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1504ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1505ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1506ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1507ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1508ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1509ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1510ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1511ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1512ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1513ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1514ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1515ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1516ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1517ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1518ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1519ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1520ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1521ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1522ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1523ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1524ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1525ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1526ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1527ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1528ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1529ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1530ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1531ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1532ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1533ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1534ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1535ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1536ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1537ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1538ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1539ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1540ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1541ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1542ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1543e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
15449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
154550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling///
15469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
15479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
154850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
1549ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1550ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1551762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
155218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
1553a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
1554762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
1555b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
1556a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
155718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
1558550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1559550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
156050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1561550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1562e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int BaseRegNum = TryParseRegister();
1563e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (BaseRegNum == -1) {
1564550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
156550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1566550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1567a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15680571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
15690571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
15700571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
15710571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    return true;
15720571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
1573a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
1574a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
1575a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
1576a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
1577a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
157805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  ARMOperand *WBOp = 0;
157905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  int OffsetRegNum = -1;
158005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  bool OffsetRegShifted = false;
15810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
158205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *ShiftAmount = 0;
158305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *Offset = 0;
1584a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
15869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
1587a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
1588a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
1589b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
159005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1591550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1592550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
159350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
159418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
1595550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
1596550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
159750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1598550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
1599762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
1600b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1601a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
160218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
1603a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
1604ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      // None of addrmode3 instruction uses "!"
1605ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode3)
1606ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return true;
1607ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
160850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
160950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                     ExclaimTok.getLoc());
1610a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
1611b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
1612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode2)
1614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        Preindexed = false;
1615a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
16160571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  } else {
16170571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    // The "[Rn" we have so far was not followed by a comma.
16180571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
161980eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // If there's anything other than the right brace, this is a post indexing
162080eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // addressing form.
1621762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
1622b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
162418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
162503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1626e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
162780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Postindexed = true;
162880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Writeback = true;
162950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1630550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
1631550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
163250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1633550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
163450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1635b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
163650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1637550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
163816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1639550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
164050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1641a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
164205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  }
1643e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
164405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  // Force Offset to exist if used.
164505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (!OffsetIsReg) {
164605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    if (!Offset)
164705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar      Offset = MCConstantExpr::Create(0, getContext());
1648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  } else {
1649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Error(E, "shift amount not supported");
1651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
1652ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
1653a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
165405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1655ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Offset, OffsetRegNum, OffsetRegShifted,
1657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     ShiftType, ShiftAmount, Preindexed,
1658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Postindexed, Negative, Writeback, S, E));
165905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (WBOp)
166005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    Operands.push_back(WBOp);
166105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
166205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  return false;
1663a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1664a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
16659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
16669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
16679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
16689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
16699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
16709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
16719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
16729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1673762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
16740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                        enum ARM_AM::ShiftOpc &ShiftType,
16759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
16769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
16779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
1678762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
1679762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
16809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
16819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
16829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
16839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
168418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
1685762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
16869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
1687b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
16889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
16899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
1690b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
16919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
16929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
169318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
16949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
1695e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    SMLoc CurLoc = OffsetRegTok.getLoc();
1696e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    OffsetRegNum = TryParseRegister();
1697e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    if (OffsetRegNum != -1) {
1698550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
1699e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner      E = CurLoc;
1700762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
17019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
1702d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
170312f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling  // If we parsed a register as the offset then there can be a shift after that.
17049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
17059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
170618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
17079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
1708b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
17099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
171018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
1711762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
17123472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
17139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
17149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
17159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
17169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
17179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
171818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
17199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
17209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
172116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1722b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
17239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
17249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
17259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
1726762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
17279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
17289c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
17299c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
17309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
1731a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
1732a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
1733a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
1734a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
17350082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
17360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                              const MCExpr *&ShiftAmount, SMLoc &E) {
173718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1738a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
1739a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
174038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
1741a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
17420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
1743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
17440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
1745a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
17460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
1747a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
17480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
1749a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
17500082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
1751a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
1752a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
1753b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
1754a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
17560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (St == ARM_AM::rrx)
17579c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
1758a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
176018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
17619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
17629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
1763b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
17649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
17659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
17669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
1767a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1768a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
1769a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1770a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
17729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
1773e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1774fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
1775762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
1776fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1777fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
1778fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
1779f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1780f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
1781fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
1782f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1783f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
1784f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
1785f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
1786f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
1787fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1788a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
1789146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
1790146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
179150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
179219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
179350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    if (!TryParseRegisterWithWriteBack(Operands))
179450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
179519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    int Res = TryParseShiftRegister(Operands);
179619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
17970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
179819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
179919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
1800e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1801e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
1802e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
180319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
180467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
180567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
1806515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
1807515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
1808515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
1809762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
181150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1812762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
181350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
181450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
181550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
1816a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
181750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseMemory(Operands);
1818d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
181950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseRegisterList(Operands);
1820d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
1821079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
1822079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1823762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1824b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
1825515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
1826515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
182750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
182950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
183050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
18319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
18329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
18337597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
18347597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
18357597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
18369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (ParsePrefix(RefKind))
18379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
18389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18397597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
18407597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
18419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
18429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18437597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
18447597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
18459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
18467597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
18479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
18489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
1849a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1850a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1851a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
18527597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
18537597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
18547597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
18557597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
18569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
18588a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
18599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
18609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
18629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
18639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
18649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
18679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
18687597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
18699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
18707597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
18719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
18729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
18739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
18749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
18769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
18789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
18799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
18809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
18819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
18829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
18839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
18849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
18869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
18879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
18889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
18899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
18909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
18919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
18929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
18949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
18959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
18969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
18979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
18989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
18999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
19009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
19019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
19039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
19049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
19069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
19079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
19099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
19109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
19129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
19139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
19149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
19159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
19169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
19179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
19199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
19209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
19219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
19239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
19249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
19259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
1926352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
1927352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
1928352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
1929badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
1930a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic,
1931a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &PredicationCode,
1932a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               bool &CarrySetting,
1933a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &ProcessorIMod) {
1934352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
1935352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
1936a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
1937352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1938badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
1939352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
1940352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
19418ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar  if (Mnemonic == "teq" || Mnemonic == "vceq" ||
19428ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "movs" ||
19438ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "svc" ||
19448ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
19458ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vmls" || Mnemonic == "vnmls") ||
19468ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacge" || Mnemonic == "vcge" ||
19478ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vclt" ||
19488ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacgt" || Mnemonic == "vcgt" ||
19498ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vcle" ||
19508ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
19518ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
1952d1f0bbee189ea7cd18d03c4f9f55d0a33b070814Jim Grosbach       Mnemonic == "vqdmlal" || Mnemonic == "bics"))
1953352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
1954badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
19553f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
19563f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
19573f00e317064560ad11168d22030416d853829f6eJim Grosbach  if (Mnemonic != "adcs") {
19583f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
19593f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
19603f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
19613f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
19623f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
19633f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
19643f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
19653f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
19663f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
19673f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
19683f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
19693f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
19703f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
19713f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
19723f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
19733f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
19743f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
19753f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
19763f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
19773f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
19783f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
19793f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
19803f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
198152925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
1982345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1983352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
1984352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
1985352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
1986352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
1987352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
1988352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
1989352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
1990352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
1991352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
1992352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
1993352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
1994352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1995a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
1996a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
1997a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
1998a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
1999a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
2000a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2001a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
2002a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
2003a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
2004a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
2005a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2006a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
2007a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
2008a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2009a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2010352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
2011352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
20123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
20143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
20153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
20163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
2017fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
2018fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2019fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
2020eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2021eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2022eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2023eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2024be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2025eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2026eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
2027be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "eor" || Mnemonic == "smlal" ||
2028ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
2029eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
2030eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
2031eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
2032eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
20333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
2034eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2035eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2036eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2037eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
2038e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes      Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
2039a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
20403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
20413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
20423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
20433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
2044fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
2045ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
2046fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
204763b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2048fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
2049badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
2050badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2051badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
2052badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2053badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2054badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
2055badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
2056badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  StringRef Head = Name.slice(Start, Next);
2057badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2058352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
2059352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
2060a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
2061352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
2062a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Head = SplitMnemonic(Head, PredicationCode, CarrySetting,
2063a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                       ProcessorIMod);
2064badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
20653a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
20669717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
20673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
20683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
20693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
20703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
20713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
20723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
20733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
20743771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
20753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode);
20763771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
20783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
20793771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
20803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
20813771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
20823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptCarrySet) {
20833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
20843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
20853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
20863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a carry set, but the user wrote one (or
20873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // misspelled another mnemonic).
20883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
20903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
20913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
20923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
20933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
20943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
20953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
20963771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
20973771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a predication code, but the user wrote
20983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // one (or misspelled another mnemonic).
20993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
21003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
2101badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
2102345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2103a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
2104a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
2105a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
2106a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
2107a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
2108a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
2109a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
2110a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
2111a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2112a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
2113a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2115345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
21165747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
21175747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
21185747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
2119a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
2120a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2121a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
21225747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
21235747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
21245747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
21255747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
2127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (ParseOperand(Operands, Head)) {
2128cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
2129cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
2130cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
2131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
2133b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
2134a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
2136fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      if (ParseOperand(Operands, Head)) {
2137cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
2138cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
2139cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
2140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
2141a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
214216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2143cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2144cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
214534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
2146cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
2147146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
214834e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
21499898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
2150ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2151ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2152fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
2153fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
2154fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2155fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
2156fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
2157fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
2158193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResultTy MatchResult, MatchResult2;
2159193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2160193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  if (MatchResult != Match_Success) {
2161193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_InvalidOperand it might be some arithmetic instruction
2162193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that does not update the condition codes.  So try adding a CCOut operand
2163193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // with a value of reg0.
2164193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    if (MatchResult == Match_InvalidOperand) {
2165193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      Operands.insert(Operands.begin() + 1,
2166193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                      ARMOperand::CreateCCOut(0,
2167193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                                  ((ARMOperand*)Operands[0])->getStartLoc()));
2168193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2169193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (MatchResult2 == Match_Success)
2170193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult = Match_Success;
217144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      else {
217244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2173193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.erase(Operands.begin() + 1);
217444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete CCOut;
217544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      }
2176193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2177193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_MnemonicFail it might be some arithmetic instruction
2178193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that updates the condition codes if it ends in 's'.  So see if the
2179193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
2180193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // operand with a value of CPSR.
2181eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng    else if (MatchResult == Match_MnemonicFail) {
2182193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      // Get the instruction mnemonic, which is the first token.
2183193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
2184193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
2185193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        // removed the 's' from the mnemonic for matching.
2186193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
2187193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
218844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
218944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.erase(Operands.begin());
219044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete OldMnemonic;
219144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.insert(Operands.begin(),
2192193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateToken(MnemonicNoS, NameLoc));
2193193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.insert(Operands.begin() + 1,
2194193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
2195193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2196193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        if (MatchResult2 == Match_Success)
2197193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby          MatchResult = Match_Success;
2198193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        else {
219944a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
220044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin());
220144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete OldMnemonic;
220244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.insert(Operands.begin(),
2203193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                          ARMOperand::CreateToken(Mnemonic, NameLoc));
220444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
220544a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin() + 1);
220644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete CCOut;
2207193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        }
2208193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      }
2209193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2210193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  }
2211193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2212e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2213fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2214fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2215e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2216e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2217e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2218e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2219e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2220e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2221e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2222e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
222316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2224e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2225e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2226e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
222716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2228e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2229e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2230e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2231e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2232b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2233b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2234fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
223516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2236c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2237146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2238fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2239fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
2240515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
2241ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2242ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2243ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
2244ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
2245515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
2246515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
2247515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
2248515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2249515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
2250515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
2251515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
2252515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
2253ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2254ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2255ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2256ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
2257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
2258ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2259ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2260ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2261ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2262ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2263ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2264ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2265aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2266ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2267ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2268ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
226916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2270ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2271ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2272ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2273b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2274ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2275ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2276ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2277b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2278ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2279ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2280ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2281515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
2282515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
2283515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2284515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2285515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2286b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2287515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2288515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2289515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2290515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2291515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2292515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2293515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2294515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
2295515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
2296515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
22976469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
22986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
22996469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
23006469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
23016469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
23026469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
23036469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
23046469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
23056469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
23066469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
23076469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
23086469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
23096469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
23106469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2311515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2312515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2313b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2314515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
23156469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
23166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
23176469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
23186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
23196469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2320642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2321642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2322642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2323515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2324515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2325515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2326515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
2327515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
2328515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
232918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2330515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2331515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
233238e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
233358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2334b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
233558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
23369e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2337515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2338515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2339515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2340515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
234118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2342b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2343515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2344515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2345515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2346515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2347515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2348515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2349515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
2350515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
2351515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
235218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2353515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2354515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
235518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
235658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2357b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
235858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2359b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2360515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2361515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2362515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2363515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
236418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2365b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2366515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
236732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
2368ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (!isThumb())
2369ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
23702a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
237132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
2372ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (isThumb())
2373ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
23742a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2375eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
23762a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2377515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2378515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2379515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
238090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
238190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
23829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2383ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
2384ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2385ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
238690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2387ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
23883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
23890692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
23900692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
23913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2392