ARMAsmParser.cpp revision 4a5ffb399f841783c201c599b88d576757f1922e
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"
11b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h"
123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h"
13ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
14ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.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
34ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
35ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
37146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
38146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
3916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
40ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
41ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
50e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int TryParseRegister();
51bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
5250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
5319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  int TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
5450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
55ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
56ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   ARMII::AddrMode AddrMode);
57fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
587597212abced110723f2fee985a7d60557c092ecEvan Cheng  bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
62a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                            enum ARM_AM::ShiftOpc &ShiftType,
669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
69762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
70762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool ParseShift(enum ARM_AM::ShiftOpc &St,
720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                  const MCExpr *&ShiftAmount, SMLoc &E);
73ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
74515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
75515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
76515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
77515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
78515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
797036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
807c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
81fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                               MCStreamer &Out);
825f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  StringRef SplitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
835f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod);
84fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes  void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
85fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
8616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
87ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
90ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
92ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
9432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
95ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
96ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
9732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
98ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
99a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
100a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1013483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1020692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1030692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
106a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
107f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocNumOperand(
108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
109f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocRegOperand(
110f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
111f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseMemBarrierOptOperand(
1128bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
113a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  OperandMatchResultTy tryParseProcIFlagsOperand(
1148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
115584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  OperandMatchResultTy tryParseMSRMaskOperand(
1168bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
117ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode2Operand(
118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
119ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode3Operand(
120ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
121f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
122f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
123f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
124f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
125f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
126f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
127f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
128f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
129c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
133ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
135ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
136ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
137ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
138ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
139ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
140f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach
141ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
142ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
143ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    : TargetAsmParser(), STI(_STI), Parser(_Parser) {
144ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
14532869205052430f45d598fba25ab878d8b29da2dEvan Cheng
146ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
147ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
148ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
149ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
15038e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1519898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
152ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
153ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
15416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
15516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1563a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
158a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
159a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
160146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
163d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
166cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
169584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
170a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
175e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
17692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ShiftedImmediate,
1770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Shifter,
1788462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
180a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
181762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
18224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
184a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
185a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
192706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
193706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
195fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
196fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
201a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
202584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
203584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
204584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
205584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
207a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2148155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
215cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
216cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
21716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2186a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
220ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARMII::AddrMode AddrMode;
221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2222637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      union {
2232637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
2242637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
2252637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      } Offset;
226146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
2270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
228146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
22950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Preindexed       : 1;
23050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Postindexed      : 1;
23150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned OffsetIsReg      : 1;
23250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Negative         : 1; // only used when OffsetIsReg is true
23350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Writeback        : 1;
234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
238e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
2390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    } Shift;
240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } ShiftedReg;
24692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
24792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
24892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
24992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
25092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    } ShiftedImm;
251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
25216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
253146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
254146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
259762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
266d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
269762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2708d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
27324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2748d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
277fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
278fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
281762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
283706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
284706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
287762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
290584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
292a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
2930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
2940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    case Shifter:
2950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      Shift = o.Shift;
2960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
297e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
298e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftedReg = o.ShiftedReg;
299e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
30092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    case ShiftedImmediate:
30192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ShiftedImm = o.ShiftedImm;
30292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
304762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
30516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
309762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
310a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
3128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
3138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
3148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
3158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
316fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
317fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
326a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3276aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3287729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
330a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
33424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
337cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
338cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
339cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
340cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
341cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
342706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
343706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
344706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
345706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
346706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
347a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
348a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
349a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
350a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
351a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
352584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
355584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
356584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @name Memory Operand Accessors
3586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @{
359ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ARMII::AddrMode getMemAddrMode() const {
360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return Mem.AddrMode;
361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemBaseRegNum() const {
3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.BaseRegNum;
3646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegNum() const {
3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.RegNum;
3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemOffset() const {
3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(!Mem.OffsetIsReg && "Invalid access!");
3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.Value;
3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegShifted() const {
3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.OffsetRegShifted;
3766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3776ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemShiftAmount() const {
3786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftAmount;
3806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc getMemShiftType() const {
3826ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftType;
3846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3856ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPreindexed() const { return Mem.Preindexed; }
3866ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPostindexed() const { return Mem.Postindexed; }
3876ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
3886ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemNegative() const { return Mem.Negative; }
3896ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemWriteback() const { return Mem.Writeback; }
3906ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
3916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @}
3926ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
394fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
396d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3973483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
3986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
3996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
4056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
40683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
40783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
40883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
40983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
41083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
41183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
41283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
41383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
41483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
41583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
41683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
41783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
41883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
41983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
42083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
42183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
4227c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
4237c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (Kind != Immediate)
4247c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
4257c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4267c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
4277c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
4287c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
4297c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
4304a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
4314a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (Kind != Immediate)
4324a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
4334a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4344a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
4354a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
4364a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
4374a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
438fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
439fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
440fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
441fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
442fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
443fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
444fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
445fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
446ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
447ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (Kind != Immediate)
448ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
449ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
450ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
451ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
452ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
453ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
454ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
455ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
456f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
457f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
458f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
459f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
460f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
461f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
462f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
463f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
464f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
465f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
466f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
467f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
468f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
469f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
470f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
471f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
4726bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
4736bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (Kind != Immediate)
4746bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
4756bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
4776bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
4786bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
4796bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
4806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
4816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
4876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
488c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
489c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (Kind != Immediate)
490c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
491c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
492c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
493c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
494c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
495c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
496b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
4978d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
4980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
4990f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
50014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
50214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
5030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool isShifter() const { return Kind == Shifter; }
504e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  bool isShiftedReg() const { return Kind == ShiftedRegister; }
50592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  bool isShiftedImm() const { return Kind == ShiftedImmediate; }
506ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool isMemMode2() const {
507ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode2)
508ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
509ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
510ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg())
511ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return true;
512ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
513ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemNegative() &&
514ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
515ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
516ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
517ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
518ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (!CE) return false;
519ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Value = CE->getValue();
520ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
521ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // The offset must be in the range 0-4095 (imm12).
522ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Value > 4095 || Value < -4095)
523ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
524ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
525ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return true;
526ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
527ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool isMemMode3() const {
528ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode3)
529ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
530ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
531ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
532ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (getMemOffsetRegShifted())
533ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return false; // No shift with offset reg allowed
534ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
535ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
536ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
537ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemNegative() &&
538ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
539ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
540ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
541ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
542ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (!CE) return false;
543ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Value = CE->getValue();
544ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
545ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // The offset must be in the range 0-255 (imm8).
546ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Value > 255 || Value < -255)
547ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
548ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
549ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
550ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
55187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  bool isMemMode5() const {
5524b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
5534b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar        getMemNegative())
55487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
555ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
5564b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
557ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
558ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
55987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    // The offset must be a multiple of 4 in the range 0-1020.
56087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    int64_t Value = CE->getValue();
56187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
56287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
563505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  bool isMemMode7() const {
564505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!isMemory() ||
565505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPreindexed() ||
566505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPostindexed() ||
567505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemOffsetIsReg() ||
568505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemNegative() ||
569505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemWriteback())
570505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
571505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
572505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
573505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!CE) return false;
574505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
575505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (CE->getValue())
576505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
577505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
578505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
579505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
580f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeRegThumb() const {
5814b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
582f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
583d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    return true;
584f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
585f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeImmThumb() const {
5864b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
587ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
588ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
5894b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
590ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
591ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
592ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    // The offset must be a multiple of 4 in the range 0-124.
593ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint64_t Value = CE->getValue();
594ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    return ((Value & 0x3) == 0 && Value <= 124);
595ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
596584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
597a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
5983483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5993483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
60014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
60114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
60214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
60314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
6043483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
6053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
6063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
6073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
6083483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
6098462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
610345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
6118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
61204f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
61304f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
6148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
6158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
616fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
617fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
618fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
619fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
620fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
621fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
622fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
623fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
624fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
625fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
626d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
627d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
628d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
629d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
630d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
631a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
632a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
633a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
634a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
635a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
636e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
637e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
638e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
639e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
640e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
641e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
642e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
643e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
644e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
64592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  void addShiftedImmOperands(MCInst &Inst, unsigned N) const {
646152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
64792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    assert(isShiftedImm() && "addShiftedImmOperands() on non ShiftedImm!");
64892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
64992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
65092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::getSORegOpc(ShiftedImm.ShiftTy, ShiftedImm.ShiftImm)));
65192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
65292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
65392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
6540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  void addShifterOperands(MCInst &Inst, unsigned N) const {
6550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
6560082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
6570082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
6580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
6590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
66087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
6617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
6625fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
6635fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
6647729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
6657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
66687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
66787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
6680f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
6690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
6700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
6710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
6720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
6730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
6740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
6750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
6763483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
6776b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
6816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
6826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
68683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
68783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
68883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
68983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
69083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
69183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
6927c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6937c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
6947c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
6957c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
6967c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
69783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
69883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
69983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
70083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
7014a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
7024a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
7034a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
7044a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
7054a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7064a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
7074a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
7084a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
709fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
710fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
711fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
712fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
713fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
714ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
715ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
716ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
717ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
718ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
719f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
720f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
721f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
722f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
723f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
724f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
725f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
726f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
727f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
728f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
729f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
730f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
731f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
732f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
7336bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
7346bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
7356bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
7366bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
7376bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
7386b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
7393483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
7403483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
7413483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
74216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
743c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
744c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
745c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
746c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
747c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
748706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
749706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
750706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
751706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
752706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
753505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
754505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
755505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
756505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
757505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
7581866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay    (void)CE;
759505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert((CE || CE->getValue() == 0) &&
760505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes           "No offset operand support in mode 7");
761505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
762505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
763ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
764ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(isMemMode2() && "Invalid mode or number of operands!");
765ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
766ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
767ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg()) {
769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
770ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
771ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
772ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
773ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      int64_t ShiftAmount = 0;
774ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
775ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (getMemOffsetRegShifted()) {
776ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShOpc = getMemShiftType();
777ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        const MCConstantExpr *CE =
778ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
779ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShiftAmount = CE->getValue();
780ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      }
781ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
782ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
783ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           ShOpc, IdxMode)));
784ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return;
785ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
786ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
787ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
788ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
789ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
790ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
791ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // the difference?
792ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
793ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(CE && "Non-constant mode 2 offset operand!");
794ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Offset = CE->getValue();
795ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
796ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Offset >= 0)
797ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
798ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           Offset, ARM_AM::no_shift, IdxMode)));
799ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    else
800ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
801ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                          -Offset, ARM_AM::no_shift, IdxMode)));
802ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
803ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
804ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
805ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(isMemMode3() && "Invalid mode or number of operands!");
806ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
807ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
808ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
809ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
810ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
811ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
812ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
813ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
814ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                                             IdxMode)));
815ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return;
816ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
817ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
818ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
819ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
820ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
821ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
822ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // the difference?
823ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
824ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(CE && "Non-constant mode 3 offset operand!");
825ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Offset = CE->getValue();
826ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
827ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Offset >= 0)
828ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
829ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           Offset, IdxMode)));
830ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    else
831ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
832ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           -Offset, IdxMode)));
833ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
834ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
83514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
83614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
83716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
8384b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
8394b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
84092b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
84180eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
84280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // the difference?
8434b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
844d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert(CE && "Non-constant mode 5 offset operand!");
845d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
846d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // The MCInst offset operand doesn't include the low two bits (like
847d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // the instruction encoding).
848d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    int64_t Offset = CE->getValue() / 4;
849d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    if (Offset >= 0)
850d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
851d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             Offset)));
852d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    else
853d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
854d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             -Offset)));
85514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
8563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
857f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
858f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
8594b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
8604b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
861f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
862ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
863f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
864f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
8654b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
8664b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
867f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(CE && "Non-constant mode offset operand!");
868f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
869ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
870ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
871584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
872584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
873584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
874584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
875584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
879a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
880a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
881b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
882b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
8833a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
8843a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
885345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
886345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
887345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
8883a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
889345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
890345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
891fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
892fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
893fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
894fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
896fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
897fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
898fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
899fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
900fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
901fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
902fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
903fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
904fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
905fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
906fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
907d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
908d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
909d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
910d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
911d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
912d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
913d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
914d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
9153a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
9163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
917762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
918762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
919762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
920762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
9213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
922a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
923a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
92450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
9253a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
926762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
927762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
928762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
9293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
930a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
931a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
932e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
933e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
934e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
935e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
936e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
937e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
938e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftTy = ShTy;
939e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.SrcReg = SrcReg;
940e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftReg = ShiftReg;
941e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftImm = ShiftImm;
942e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
943e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
944e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
945e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
946e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
94792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
94892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
94992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
95092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
95192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
95292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->ShiftedImm.ShiftTy = ShTy;
95392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->ShiftedImm.SrcReg = SrcReg;
95492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->ShiftedImm.ShiftImm = ShiftImm;
95592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
95692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
95792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
95892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
95992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
9600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
9620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    ARMOperand *Op = new ARMOperand(Shifter);
9630082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->Shift.ShiftTy = ShTy;
9640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
9650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
9660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
9670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
9680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9697729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
9705fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
971cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
9720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
9730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    if (ARM::DPRRegClass.contains(Regs.front().first))
9750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
9760f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    else if (ARM::SPRRegClass.contains(Regs.front().first))
9770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
9780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
9805fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
9817729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
98224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
983cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
984cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
985cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
9868d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
9878d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
9888d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
9893a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
9903a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
991762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
992762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
993762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
9943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
995cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
996cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
997ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
998ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               bool OffsetIsReg, const MCExpr *Offset,
999ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               int OffsetRegNum, bool OffsetRegShifted,
10000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               enum ARM_AM::ShiftOpc ShiftType,
10013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
10023a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
10033a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
1004023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((OffsetRegNum == -1 || OffsetIsReg) &&
1005023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegNum must imply OffsetIsReg!");
1006023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!OffsetRegShifted || OffsetIsReg) &&
1007023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegShifted must imply OffsetIsReg!");
1008d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert((Offset || OffsetIsReg) &&
1009d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar           "Offset must exists unless register offset is used!");
1010023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
1011023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have shift amount without shifted register offset!");
1012023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!Offset || !OffsetIsReg) &&
1013023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have expression offset and register offset!");
1014023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar
10153a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
1016ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Op->Mem.AddrMode = AddrMode;
1017762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
1018762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
10192637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    if (OffsetIsReg)
10202637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.RegNum = OffsetRegNum;
10212637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    else
10222637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.Value = Offset;
1023762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
1024762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
1025762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
1026762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
1027762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
1028762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
1029762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
103016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1031762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1032762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
10333a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1035706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1036706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
1037706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
1038706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1039706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1040706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1041706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1042706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1043a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1044a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1045a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
1046a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1047a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1048a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1049a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1050a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1051584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1052584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1053584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
1054584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1055584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1056584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1059a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1060a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1061a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1062a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1063b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1064fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
1065fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
10666a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1067fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1068d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
1069d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1070d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
1071fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
1072fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1073fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1074fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
1075fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1076fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1077584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
1078584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1079584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
1080fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
1081fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1082fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1083706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
1084706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1085706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
1086fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
10876ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
1088ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
1089ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << " base:" << getMemBaseRegNum();
10906ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg()) {
10916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:<register " << getMemOffsetRegNum();
10926ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      if (getMemOffsetRegShifted()) {
10936ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-type:" << getMemShiftType();
10946ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-amount:" << *getMemShiftAmount();
10956ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      }
10966ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    } else {
10976ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:" << *getMemOffset();
10986ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    }
10996ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg())
11006ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (offset-is-reg)";
11016ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPreindexed())
11026ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (pre-indexed)";
11036ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPostindexed())
11046ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (post-indexed)";
11056ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemNegative())
11066ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (negative)";
11076ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemWriteback())
11086ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (writeback)";
11096ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1110fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1111a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
1112a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1113a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1114a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1115a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1116a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1117a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1118a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1119a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1120fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
112150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1122fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
11230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  case Shifter:
1124e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
1125e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
1126e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
112792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1128e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ShiftedReg.SrcReg
1129e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
1130e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ", " << ShiftedReg.ShiftReg << ", "
1131e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
1132e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
11330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
113492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  case ShiftedImmediate:
113592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
113692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ShiftedImm.SrcReg
113792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedImm.ShiftImm))
113892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ", " << ARM_AM::getSORegOffset(ShiftedImm.ShiftImm)
113992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
114092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
11410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
11420f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
11430f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
11448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
11458d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
11465fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
11475fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
11487729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
11497729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
11507729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
11518d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
11528d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
11538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
11548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
11558d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1156fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1157fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1159fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1160fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
11613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
11633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
11643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
11663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
11683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
116969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
117069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
1171bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  RegNo = TryParseRegister();
1172bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1173bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1174bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1175bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
11769c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1177e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1178e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
11793a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
1180e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() {
118118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1183d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1184a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1185a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
11860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
11870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
11880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
11890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
11900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
11910c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
11920c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
11930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
11940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
11950c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
11960c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
11970c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
119869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1199b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1200e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1201e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1202d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
120319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
120419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
120519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
120619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
120719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
120819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbachint ARMAsmParser::TryParseShiftRegister(
12090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
12100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
12110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
12120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
12130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
12150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
12160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
12170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
12180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
12190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
12200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
12210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
12220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
12230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
122519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
12260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1227e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1228e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1230e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1232eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1233e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1237e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1238e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
124919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
125019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
125119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
125219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1253e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1254e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
125519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
125619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
125719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
125819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1259e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1260e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1262e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1263e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1264e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1265e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
126619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
126719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1268e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1269e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
1270e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftReg = TryParseRegister();
1271e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
127219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
127319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
127419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
127519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
127619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
127719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1278e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
127919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
128019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1281e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1282e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
128392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
128492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1285e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                                       ShiftReg, Imm,
12860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
128792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
128892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
128992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
12900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
129119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
12920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
12930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
129550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
129650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
129750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1298e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1299e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1300e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
130150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
130250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1303e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
1304e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int RegNo = TryParseRegister();
1305e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
130650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1307d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
130850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1310e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1311e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
131250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
131350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1314e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
131599e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
131699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
131750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1319a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1322fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1323fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1324e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1325e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1326e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1327e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1328e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1329fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1330e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1331e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1332e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1333e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1334e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1335e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1336e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1337e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1338e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1339e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1340e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1341e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1342e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1343e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1344e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1345e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1346fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1347e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1348e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1349e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1350e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1351e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1352e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1353e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1354e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1355e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1356e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1357e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1358e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1359e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1360e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1361e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1362e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1363f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1364fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1365fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1366f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1367f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1368e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1370e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1372fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1373e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1374f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1375e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1376e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1378f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1379fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1380fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1381f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1382fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1383fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1384f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1385f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1386fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1387fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1388fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1389fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1390fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1391fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1392f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1394fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1395fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1396f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1397e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1398e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1399c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1400c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
140150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
140250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
140318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1404a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1405e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
140616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
14077729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
14087729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
14095fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1410d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
14117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1412e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
14137729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1414d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
141518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1416d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1417c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1418c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
141950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1420c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1421e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14221d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling    int RegNum = TryParseRegister();
1423c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1424c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
142550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1426c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1427d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1428e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1429e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1430e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1431e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1432e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1433e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1434e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1435e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1436e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1437e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1438e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
14397729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
14407729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1441e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1442e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
144318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1444c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1445c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
144650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1447c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1448d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1449e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1450e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
145103f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1452e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
14535fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1454e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1455e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14567caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
14578e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
14588e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
14597caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
14607caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
14617caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1462e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
14637729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
14647caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1465e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14668e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1467e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
146850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1469e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1470e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14718e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1472e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1473e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1474e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14758e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
14768e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1477e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1478e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
147950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
148050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1481d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1482d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1483f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1484f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1485f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1486706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1487706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1488706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1489706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1490706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1491706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1492706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1493706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1494032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
1495706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1496032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
1497706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1499032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
1500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1501032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
1502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1503706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1505706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1507f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1508706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1509706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1510706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1511f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1512706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1513706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
15148bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1528a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1530a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1532a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1534a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1539a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1540a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1543584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1545584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1551584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1552584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1553584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1554b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
1555584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1556584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1557584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1558584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1559584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1560584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1561584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1562584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1563584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1564584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1565b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
1566584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1567584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1568584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1569584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
15704b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1571584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1572584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1573584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1574584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
15754b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1576584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
157756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
157856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1579584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1580584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1581584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1582584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1585584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1591584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1593584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1596584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1600584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1601584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1605584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1606584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1607a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1608a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1609ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1612e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode2))
1615ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return MatchOperand_NoMatch;
1616ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return MatchOperand_Success;
1618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1620ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1621ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1622ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1623ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1624ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1625ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode3))
1626ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1627ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1628ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return MatchOperand_Success;
1629ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1630ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1631f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1632f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
1633f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
1634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1638f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1639f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
1640f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
1641f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
1642f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
1643f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1644f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1645f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
1647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1648f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
1649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1653f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
1654f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1655f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
1656f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
1657f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1658f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
1659f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1660f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1661f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1662f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
1663f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
1664f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1665f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1666f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
1667f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
1668f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
1669f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1670f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1671f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1672f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
1673f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1674f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
1675f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
1676f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1677c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1678c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1679c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1680c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
1681c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1682c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
1683c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
1684c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1685c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
1686c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
1687c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
1688c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
1689c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
1690c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1691c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
1692c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
1693c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
1694c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1695c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
1696c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
1697c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
1698c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
1699c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
1700c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1701ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1702ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1703ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1704ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1705ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1706ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1707ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1708ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1709ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1710ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1711ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1712ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1713ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1714ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1715ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1716ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1717ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1718ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1719ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1720ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1721ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1722ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1723ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1724ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1725ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1726ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1727ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1728ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1729ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1730ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1731ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1732ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1733ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1734ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1735ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1736ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1737ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1738ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1739ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1740ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1741ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1742ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1743ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1744ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1745ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1746ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1747ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1748ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1749ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1750ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1751ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1752ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1753ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1754ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1755ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1756ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1757ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1758ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1759ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1760ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1761e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
17629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
176350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling///
17649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
17659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
176650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
1767ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1769762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
177018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
1771a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
1772762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
1773b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
1774a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
177518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
1776550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1777550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
177850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1779550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1780e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int BaseRegNum = TryParseRegister();
1781e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (BaseRegNum == -1) {
1782550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
178350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1784550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1785a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17860571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
17870571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
17880571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
17890571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    return true;
17900571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
1791a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
1792a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
1793a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
1794a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
1795a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
179605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  ARMOperand *WBOp = 0;
179705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  int OffsetRegNum = -1;
179805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  bool OffsetRegShifted = false;
17990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
180005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *ShiftAmount = 0;
180105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *Offset = 0;
1802a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
18039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
18049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
1805a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
1806a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
1807b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
180805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1809550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1810550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
181150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
181218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
1813550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
1814550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
181550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1816550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
1817762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
1818b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1819a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
182018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
1821a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
1822ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      // None of addrmode3 instruction uses "!"
1823ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode3)
1824ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return true;
1825ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
182650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
182750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                     ExclaimTok.getLoc());
1828a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
1829b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
1830ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1831ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode2)
1832ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        Preindexed = false;
1833a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
18340571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  } else {
18350571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    // The "[Rn" we have so far was not followed by a comma.
18360571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
183780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // If there's anything other than the right brace, this is a post indexing
183880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // addressing form.
1839762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
1840b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1841a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
184218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
184303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1844e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
184580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Postindexed = true;
184680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Writeback = true;
184750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1848550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
1849550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
185050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1851550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
185250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1853b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
185450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1855550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
185616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1857550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
185850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1859a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
186005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  }
1861e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
186205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  // Force Offset to exist if used.
186305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (!OffsetIsReg) {
186405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    if (!Offset)
186505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar      Offset = MCConstantExpr::Create(0, getContext());
1866ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  } else {
1867ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1868ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Error(E, "shift amount not supported");
1869ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
1870ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
1871a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
187205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1873ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1874ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Offset, OffsetRegNum, OffsetRegShifted,
1875ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     ShiftType, ShiftAmount, Preindexed,
1876ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Postindexed, Negative, Writeback, S, E));
187705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (WBOp)
187805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    Operands.push_back(WBOp);
187905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
188005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  return false;
1881a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1882a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
18839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
18849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
18859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
18869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
18879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
18889c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
18899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
18909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1891762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
18920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                        enum ARM_AM::ShiftOpc &ShiftType,
18939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
18949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
18959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
1896762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
1897762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
18989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
18999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
19009c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
19019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
190218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
1903762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
19049c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
1905b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
19069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
19079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
1908b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
19099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
19109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
191118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
19129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
1913e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    SMLoc CurLoc = OffsetRegTok.getLoc();
1914e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    OffsetRegNum = TryParseRegister();
1915e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    if (OffsetRegNum != -1) {
1916550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
1917e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner      E = CurLoc;
1918762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
19199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
1920d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
192112f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling  // If we parsed a register as the offset then there can be a shift after that.
19229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
19239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
192418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
19259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
1926b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
19279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
192818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
1929762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
19303472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
19319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
19329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
19339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
19349c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
19359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
193618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
19379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
19389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
193916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1940b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
19419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
19429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
19439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
1944762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
19459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
19469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
19479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
19489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
1949a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
1950a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
1951a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
1952a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
19530082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
19540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                              const MCExpr *&ShiftAmount, SMLoc &E) {
195518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1956a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
1957a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
195838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
1959a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
19600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
1961a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
19620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
1963a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
19640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
1965a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
19660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
1967a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
19680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
1969a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
1970a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
1971b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
1972a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
19739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
19740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (St == ARM_AM::rrx)
19759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
1976a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
19779c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
197818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
19799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
19809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
1981b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
19829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
19839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
19849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
1985a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1986a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
1987a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1988a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
19899c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
19909c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
1991e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1992fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
1993762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
1994fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1995fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
1996fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
1997f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1998f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
1999fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
2000f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
2001f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
2002f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
2003f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
2004f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
2005fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2006a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
2007146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
2008146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
200950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
201019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
201150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    if (!TryParseRegisterWithWriteBack(Operands))
201250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
201319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    int Res = TryParseShiftRegister(Operands);
201419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
20150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
201619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
201719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
2018e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2019e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
2020e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
202119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
202267b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
202367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
2024515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
2025515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
2026515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
2027762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2028515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
202950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2030762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
203150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
203250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
203350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
2034a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
203550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseMemory(Operands);
2036d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
203750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseRegisterList(Operands);
2038d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
2039079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
2040079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
2041762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2042b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2043515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
2044515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
204550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2046762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
204750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
204850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
20499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
20509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
20517597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
20527597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
20537597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
20549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (ParsePrefix(RefKind))
20559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
20569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20577597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
20587597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
20599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
20609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20617597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
20627597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
20639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
20647597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
20659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
20669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
2067a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2068a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2069a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
20707597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
20717597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
20727597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
20737597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
20749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
20768a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
20779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
20789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
20809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
20819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
20829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
20859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
20867597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
20879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
20887597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
20899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
20909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
20919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
20929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
20949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
20969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
20979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
20989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
21009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
21019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
21029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
21049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
21059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
21069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
21079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
21089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
21099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
21109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
21129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
21139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
21149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
21159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
21169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
21189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
21199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
21219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
21229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
21249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
21259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
21279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
21289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
21309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
21319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
21329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
21339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
21349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
21359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
21379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
21389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
21399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
21409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
21419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
21429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
21439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
2144352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
2145352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
2146352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
2147badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
21485f16057d1e4b711d492091bc555693a03d4a1b6eJim GrosbachStringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic,
21495f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
21505f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
21515f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &ProcessorIMod) {
2152352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
2153352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
2154a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
2155352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2156badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
2157352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
2158352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
21595f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
21605f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
21615f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
21625f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
21635f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
21645f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
21655f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
21665f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
2167352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
2168badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
21693f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
21703f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
2171ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
2172bf2845c0d8a77d24e9971871badeba8cee7b2648Jim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls") {
21733f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
21743f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
21753f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
21763f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
21773f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
21783f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
21793f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
21803f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
21813f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
21823f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
21833f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
21843f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
21853f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
21863f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
21873f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
21883f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
21893f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
21903f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
21913f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
21923f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
21933f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
21943f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
21953f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
219652925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
2197345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2198352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
2199352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
2200352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
2201352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
22025f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
22035f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
22045f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
22055f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) {
2206352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
2207352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
2208352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
2209352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2210a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
2211a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
2212a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
2213a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
2214a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
2215a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2216a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
2217a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
2218a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
2219a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
2220a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2221a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
2222a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
2223a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2224a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2225352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
2226352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
22273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
22283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
22293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
22303771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
22313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
2232fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
2233fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2234fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
2235eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2236eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2237eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2238eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2239be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2240eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2241eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
2242be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "eor" || Mnemonic == "smlal" ||
2243ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
2244eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
2245eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
2246eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
2247eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
22483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
2249eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2250eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2251eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2252eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
22535f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
2254c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      Mnemonic == "setend" ||
22555f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
22563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
22573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
22583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
22593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
2260fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
2261ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
2262fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
226363b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2264fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
2265badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
2266badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2267badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
2268badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2269badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2270badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
2271badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
2272ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
2273badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2274352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
2275352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
2276a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
2277352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
2278ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting,
2279c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                           ProcessorIMod);
2280badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2281ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
2282ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2283ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
2284ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
22859717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
22863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
22873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
22883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
22893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
22903771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
22913771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
22923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
22933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
2294ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  GetMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
22953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
229633c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
229733c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
229833c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
229933c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
2300ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
230133c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
230233c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
2303c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
2304c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
2305c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
2306c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
2307c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
2308c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
2309c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
231033c16a27370939de39679245c3dff72383c210bdJim Grosbach
23113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
23123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
23133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
23143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
23153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
231633c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (CanAcceptCarrySet)
23173771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
23183771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
23193771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
23203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
23213771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
23223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
23233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
2324badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
2325345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2326a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
2327a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
2328a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
2329a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
2330a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
2331a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
2332a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
2333a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
2334a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2335a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
2336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2338345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
23395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
23405747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
23415747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
2342a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
2343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2344a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
23455747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
23465747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
23475747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
23485747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2349a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
2350ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (ParseOperand(Operands, Mnemonic)) {
2351cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
2352cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
2353cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
2354a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2355a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
2356b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
2357a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2358a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
2359ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      if (ParseOperand(Operands, Mnemonic)) {
2360cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
2361cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
2362cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
2363a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
2364a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
236516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2366cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2367cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
236834e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
2369cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
2370146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
237134e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
2372ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2373ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2374ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
2375ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
2376ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
2377ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // operand if that's the instruction we're trying to match.
2378ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  //
2379ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // We do this post-processing of the explicit operands rather than just
2380ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // conditionally adding the cc_out in the first place because we need
2381ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // to check the type of the parsed immediate operand.
2382ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  if (Mnemonic == "mov" && Operands.size() > 4 &&
2383ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
2384731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
2385731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0) {
2386ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
2387ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
2388ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
2389ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
2390ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
23919898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
2392ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2393ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2394fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
2395fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
2396fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2397fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
2398fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
2399fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
24005a18700470f0831b9b2af78862672561dd980345Jim Grosbach  MatchResultTy MatchResult;
2401193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2402193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2403e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2404fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2405fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2406e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2407e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2408e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2409e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2410e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2411e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2412e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2413e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
241416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2415e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2416e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2417e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
241816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2419e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2420e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2421e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2422e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2423b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2424b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2425fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
242616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2427c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2428146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2429fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2430fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
2431515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
2432ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2433ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2434ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
2435ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
2436515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
2437515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
2438515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
2439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2440515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
2441515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
2442515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
2443515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
2444ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2445ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2446ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2447ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
2448ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
2449ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2450ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2451ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2452ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2453ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2454ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2455ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2456aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2457ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2458ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2459ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
246016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2461ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2462ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2463ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2464b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2465ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2466ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2467ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2468b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2469ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2470ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2471ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2472515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
2473515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
2474515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2475515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2476515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2477b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2478515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2479515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2480515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2481515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2482515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2483515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2484515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2485515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
2486515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
2487515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
24886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
24896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
24906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
24916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
24926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
24936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
24946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
24956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
24966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
24976469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
24986469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
24996469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
25006469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
25016469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2502515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2503515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2504b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2505515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
25066469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
25076469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
25086469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
25096469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
25106469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2511642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2512642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2513642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2514515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2515515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2516515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2517515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
2518515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
2519515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
252018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2521515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2522515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
252338e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
252458c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2525b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
252658c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
25279e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2528515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2529515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2530515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2531515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
253218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2533b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2534515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2535515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2536515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2537515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2538515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2539515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2540515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
2541515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
2542515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
254318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2544515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2545515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
254618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
254758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2548b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
254958c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2550b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2551515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2552515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2553515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2554515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
255518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2556b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2557515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
255832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
2559ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (!isThumb())
2560ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
25612a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
256232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
2563ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (isThumb())
2564ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
25652a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2566eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
25672a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2568515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2569515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2570515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
257190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
257290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
25739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2574ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
2575ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2576ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
257790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2578ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
25793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
25800692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
25810692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
25823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2583