ARMAsmParser.cpp revision 92a202213bb4c20301abf6ab64e46df3695e60bf
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  }
129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
132ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
133ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
134ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
135ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
136ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
137ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
138ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
139f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach
140ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
141ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
142ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    : TargetAsmParser(), STI(_STI), Parser(_Parser) {
143ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
14432869205052430f45d598fba25ab878d8b29da2dEvan Cheng
145ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
146ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
148ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
14938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1509898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
151ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
152ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
15316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
15416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1553a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1563a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
157a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
158a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
159146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
160762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
162d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
163fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
165cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
166706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1678462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
168584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
169a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1718d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1720f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
174e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
17592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ShiftedImmediate,
1760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Shifter,
1778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
178a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
179a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
180762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
18124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
184a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1858462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1888462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
189706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
190706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
191706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
192706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
193fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
195fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
196fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
197a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
198a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
199a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
200a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
201584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
202584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
203584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
204584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
205a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
206a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
207a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
208a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2138155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
214cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
215cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
21616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2176a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
219ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARMII::AddrMode AddrMode;
220a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2212637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      union {
2222637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
2232637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
2242637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      } Offset;
225146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
2260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
227146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
22850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Preindexed       : 1;
22950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Postindexed      : 1;
23050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned OffsetIsReg      : 1;
23150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Negative         : 1; // only used when OffsetIsReg is true
23250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Writeback        : 1;
233a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
237e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
2380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    } Shift;
239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } ShiftedReg;
24592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
24692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
24792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
24892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
24992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    } ShiftedImm;
250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
25116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
252146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
253146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
258762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2618462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
262762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
265d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2698d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2710f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
27224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
277fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
280762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
281706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
283706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
286762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
290a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
291a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
2920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
2930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    case Shifter:
2940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      Shift = o.Shift;
2950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
296e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
297e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftedReg = o.ShiftedReg;
298e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
29992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    case ShiftedImmediate:
30092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ShiftedImm = o.ShiftedImm;
30192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
302762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
303762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
30416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
305762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
306762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
307762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
308762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
309a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3108462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
3118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
3128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
3138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
3148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
315fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
316fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
317fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
320a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
323a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
324a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
325a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3266aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3277729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
329a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3305fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
33324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
336cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
337cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
338cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
339cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
340cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
341706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
342706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
343706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
344706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
345706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
346a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
347a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
348a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
349a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
350a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
351584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
352584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
353584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
354584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
355584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @name Memory Operand Accessors
3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @{
358ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ARMII::AddrMode getMemAddrMode() const {
359ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return Mem.AddrMode;
360ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemBaseRegNum() const {
3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.BaseRegNum;
3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegNum() const {
3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.RegNum;
3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemOffset() const {
3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(!Mem.OffsetIsReg && "Invalid access!");
3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.Value;
3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegShifted() const {
3736ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.OffsetRegShifted;
3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemShiftAmount() const {
3776ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftAmount;
3796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc getMemShiftType() const {
3816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3826ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftType;
3836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPreindexed() const { return Mem.Preindexed; }
3856ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPostindexed() const { return Mem.Postindexed; }
3866ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
3876ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemNegative() const { return Mem.Negative; }
3886ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemWriteback() const { return Mem.Writeback; }
3896ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
3906ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @}
3916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
392fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3948462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
395d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3963483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
3976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
3986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
3996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
4046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
40583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
40683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
40783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
40883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
40983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
41083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
41183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
41283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
41383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
41483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
41583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
41683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
41783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
41883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
41983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
42083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
421fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
422fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
423fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
424fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
425fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
426fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
427fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
428fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
429ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
430ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (Kind != Immediate)
431ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
432ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
433ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
434ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
435ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
436ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
437ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
438ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
439f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
440f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
441f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
442f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
443f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
444f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
445f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
446f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
447f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
448f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
449f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
450f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
451f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
452f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
453f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
454f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
4556bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
4566bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (Kind != Immediate)
4576bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
4586bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4596bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
4606bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
4616bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
4626bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
4636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
4646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4656b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4676b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
4706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
471b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
4728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
4730f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
4740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
47514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
476706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
47714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
4780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool isShifter() const { return Kind == Shifter; }
479e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  bool isShiftedReg() const { return Kind == ShiftedRegister; }
48092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  bool isShiftedImm() const { return Kind == ShiftedImmediate; }
481ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool isMemMode2() const {
482ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode2)
483ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
484ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
485ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg())
486ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return true;
487ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
488ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemNegative() &&
489ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
490ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
491ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
492ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
493ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (!CE) return false;
494ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Value = CE->getValue();
495ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
496ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // The offset must be in the range 0-4095 (imm12).
497ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Value > 4095 || Value < -4095)
498ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
499ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
500ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return true;
501ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
502ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool isMemMode3() const {
503ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode3)
504ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
505ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
506ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
507ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (getMemOffsetRegShifted())
508ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return false; // No shift with offset reg allowed
509ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
510ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
511ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
512ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemNegative() &&
513ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
514ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
515ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
516ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
517ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (!CE) return false;
518ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Value = CE->getValue();
519ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
520ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // The offset must be in the range 0-255 (imm8).
521ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Value > 255 || Value < -255)
522ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
523ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
524ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
525ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
52687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  bool isMemMode5() const {
5274b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
5284b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar        getMemNegative())
52987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
530ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
5314b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
532ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
533ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
53487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    // The offset must be a multiple of 4 in the range 0-1020.
53587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    int64_t Value = CE->getValue();
53687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
53787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
538505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  bool isMemMode7() const {
539505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!isMemory() ||
540505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPreindexed() ||
541505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPostindexed() ||
542505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemOffsetIsReg() ||
543505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemNegative() ||
544505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemWriteback())
545505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
546505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
547505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
548505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!CE) return false;
549505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
550505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (CE->getValue())
551505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
552505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
553505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
554505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
555f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeRegThumb() const {
5564b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
557f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
558d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    return true;
559f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
560f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeImmThumb() const {
5614b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
562ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
563ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
5644b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
565ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
566ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
567ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    // The offset must be a multiple of 4 in the range 0-124.
568ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint64_t Value = CE->getValue();
569ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    return ((Value & 0x3) == 0 && Value <= 124);
570ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
571584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
572a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
5733483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5743483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
57514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
57614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
57714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
57814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
5793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
5803483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
5813483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
5823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
5833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5848462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
585345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
5868462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
58704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
58804f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
5898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
5908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
591fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
592fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
593fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
594fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
595fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
596fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
597fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
598fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
599fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
600fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
601d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
602d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
603d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
604d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
605d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
606a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
607a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
608a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
609a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
610a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
611e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
612e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
613e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
614e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
615e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
616e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
617e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
618e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
619e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
62092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  void addShiftedImmOperands(MCInst &Inst, unsigned N) const {
62192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    assert(N == 3 && "Invalid number of operands!");
62292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    assert(isShiftedImm() && "addShiftedImmOperands() on non ShiftedImm!");
62392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
62492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    if (ShiftedImm.ShiftTy == ARM_AM::rrx)
62592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
62692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    else
62792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
62892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
62992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::getSORegOpc(ShiftedImm.ShiftTy, ShiftedImm.ShiftImm)));
63092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
63192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
63292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
6330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  void addShifterOperands(MCInst &Inst, unsigned N) const {
6340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
6350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
6360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
6370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
6380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
63987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
6407729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
6415fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
6425fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
6437729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
6447729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
64587f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
64687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
6470f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
6480f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
6490f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
6500f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
6510f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
6520f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
6530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
6540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
6553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
6566b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6576b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6586b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6596b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
6606b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
6616b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6626b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6636b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6646b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
66583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
66683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
66783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
66883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
66983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
67083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
67183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
67283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
67383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
67483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
675fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
676fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
677fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
678fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
679fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
680ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
681ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
682ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
683ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
684ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
685f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
686f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
687f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
688f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
689f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
690f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
691f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
692f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
693f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
694f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
695f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
696f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
697f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
698f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
6996bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
7006bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
7016bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
7026bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
7036bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
7046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
7053483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
7063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
7073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
70816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
709706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
710706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
711706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
712706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
713706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
714505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
715505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
716505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
717505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
718505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
7191866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay    (void)CE;
720505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert((CE || CE->getValue() == 0) &&
721505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes           "No offset operand support in mode 7");
722505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
723505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
724ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
725ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(isMemMode2() && "Invalid mode or number of operands!");
726ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
727ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
728ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
729ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg()) {
730ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
731ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
732ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
733ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
734ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      int64_t ShiftAmount = 0;
735ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
736ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (getMemOffsetRegShifted()) {
737ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShOpc = getMemShiftType();
738ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        const MCConstantExpr *CE =
739ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
740ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShiftAmount = CE->getValue();
741ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      }
742ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
743ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
744ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           ShOpc, IdxMode)));
745ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return;
746ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
747ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
748ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
749ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
750ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
751ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
752ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // the difference?
753ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
754ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(CE && "Non-constant mode 2 offset operand!");
755ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Offset = CE->getValue();
756ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
757ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Offset >= 0)
758ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
759ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           Offset, ARM_AM::no_shift, IdxMode)));
760ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    else
761ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
762ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                          -Offset, ARM_AM::no_shift, IdxMode)));
763ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
764ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
765ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
766ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(isMemMode3() && "Invalid mode or number of operands!");
767ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
768ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
769ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
770ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
771ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
772ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
773ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
774ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
775ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                                             IdxMode)));
776ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return;
777ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
778ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
779ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
780ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
781ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
782ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
783ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // the difference?
784ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
785ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(CE && "Non-constant mode 3 offset operand!");
786ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Offset = CE->getValue();
787ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
788ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Offset >= 0)
789ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
790ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           Offset, IdxMode)));
791ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    else
792ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
793ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           -Offset, IdxMode)));
794ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
795ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
79614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
79714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
79816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
7994b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
8004b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
80192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
80280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
80380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // the difference?
8044b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
805d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert(CE && "Non-constant mode 5 offset operand!");
806d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
807d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // The MCInst offset operand doesn't include the low two bits (like
808d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // the instruction encoding).
809d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    int64_t Offset = CE->getValue() / 4;
810d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    if (Offset >= 0)
811d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
812d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             Offset)));
813d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    else
814d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
815d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             -Offset)));
81614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
8173483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
818f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
819f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
8204b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
8214b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
822f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
823ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
824f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
825f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
8264b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
8274b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
828f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(CE && "Non-constant mode offset operand!");
829f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
830ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
831ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
832584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
833584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
834584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
835584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
836584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
837a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
838a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
839a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
840a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
841a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
842b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
843b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
8443a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
8453a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
846345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
847345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
848345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
8493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
850345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
851345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
852fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
853fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
854fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
855fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
856fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
857fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
858fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
859fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
860fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
861fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
862fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
863fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
864fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
865fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
866fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
867fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
868d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
869d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
870d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
871d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
872d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
873d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
874d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
875d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
8763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
8773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
878762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
879762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
880762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
881762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
8823a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
883a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
884a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
88550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
8863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
887762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
888762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
889762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8903a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
891a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
892a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
893e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
894e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
895e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
896e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
897e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
898e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
899e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftTy = ShTy;
900e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.SrcReg = SrcReg;
901e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftReg = ShiftReg;
902e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->ShiftedReg.ShiftImm = ShiftImm;
903e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
904e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
905e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
906e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
907e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
90892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
90992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
91092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
91192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
91292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
91392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->ShiftedImm.ShiftTy = ShTy;
91492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->ShiftedImm.SrcReg = SrcReg;
91592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->ShiftedImm.ShiftImm = ShiftImm;
91692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
91792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
91892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
91992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
92092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
9210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
9220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
9230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    ARMOperand *Op = new ARMOperand(Shifter);
9240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->Shift.ShiftTy = ShTy;
9250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
9260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
9270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
9280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
9290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9307729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
9315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
932cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
9330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
9340f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9350f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    if (ARM::DPRRegClass.contains(Regs.front().first))
9360f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
9370f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    else if (ARM::SPRRegClass.contains(Regs.front().first))
9380f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
9390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
9415fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
9427729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
94324d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
944cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
945cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
946cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
9478d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
9488d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
9498d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
9503a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
9513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
952762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
953762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
954762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
9553a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
956cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
957cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
958ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
959ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               bool OffsetIsReg, const MCExpr *Offset,
960ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               int OffsetRegNum, bool OffsetRegShifted,
9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               enum ARM_AM::ShiftOpc ShiftType,
9623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
9633a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
9643a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
965023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((OffsetRegNum == -1 || OffsetIsReg) &&
966023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegNum must imply OffsetIsReg!");
967023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!OffsetRegShifted || OffsetIsReg) &&
968023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegShifted must imply OffsetIsReg!");
969d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert((Offset || OffsetIsReg) &&
970d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar           "Offset must exists unless register offset is used!");
971023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
972023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have shift amount without shifted register offset!");
973023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!Offset || !OffsetIsReg) &&
974023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have expression offset and register offset!");
975023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar
9763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
977ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Op->Mem.AddrMode = AddrMode;
978762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
979762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
9802637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    if (OffsetIsReg)
9812637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.RegNum = OffsetRegNum;
9822637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    else
9832637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.Value = Offset;
984762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
985762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
986762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
987762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
988762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
989762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
990762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
99116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
992762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
993762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
9943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
995a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
996706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
997706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
998706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
999706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1000706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1001706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1002706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1003706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1004a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1005a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1006a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
1007a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1008a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1009a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1010a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1011a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1012584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1013584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1014584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
1015584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1016584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1017584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1018584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1019584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1020a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1021a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1022a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1023a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1024b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1025fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
1026fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
10276a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1028fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1029d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
1030d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1031d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
1032fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
1033fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1034fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1035fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
1036fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1037fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1038584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
1039584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1040584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
1041fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
1042fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1043fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1044706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
1045706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1046706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
1047fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
10486ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
1049ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
1050ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << " base:" << getMemBaseRegNum();
10516ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg()) {
10526ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:<register " << getMemOffsetRegNum();
10536ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      if (getMemOffsetRegShifted()) {
10546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-type:" << getMemShiftType();
10556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-amount:" << *getMemShiftAmount();
10566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      }
10576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    } else {
10586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:" << *getMemOffset();
10596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    }
10606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg())
10616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (offset-is-reg)";
10626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPreindexed())
10636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (pre-indexed)";
10646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPostindexed())
10656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (post-indexed)";
10666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemNegative())
10676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (negative)";
10686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemWriteback())
10696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (writeback)";
10706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1071fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1072a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
1073a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1074a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1075a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1076a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1077a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1078a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1079a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1080a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1081fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
108250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1083fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
10840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  case Shifter:
1085e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
1086e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
1087e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
108892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1089e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ShiftedReg.SrcReg
1090e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
1091e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ", " << ShiftedReg.ShiftReg << ", "
1092e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
1093e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
10940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
109592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  case ShiftedImmediate:
109692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
109792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ShiftedImm.SrcReg
109892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedImm.ShiftImm))
109992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ", " << ARM_AM::getSORegOffset(ShiftedImm.ShiftImm)
110092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
110192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
11020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
11030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
11040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
11058d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
11068d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
11075fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
11085fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
11097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
11107729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
11117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
11128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
11138d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
11148d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
11158d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
11168d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1117fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1118fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1119fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1120fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1121fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
11223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
11243483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
11253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11263483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
11273483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
11293483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
113069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
113169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
1132bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  RegNo = TryParseRegister();
1133bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1134bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1135bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1136bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
11379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1138e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1139e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
11403a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
1141e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() {
114218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1143a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1144d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1145a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1146a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
11470c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
11480c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
11490c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
11500c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
11510c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
11520c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
11530c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
11540c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
11550c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
11560c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
11570c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
11580c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
115969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1160b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1161e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1162e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1163d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
116419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
116519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
116619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
116719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
116819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
116919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbachint ARMAsmParser::TryParseShiftRegister(
11700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
11710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
11720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
11730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
11740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
11750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
11760082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
11770082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
11780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
11790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
11800082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
11810082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
11820082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
11830082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
11840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
11850082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
118619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
11870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1188e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1189e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1190e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1191e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1192e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1193eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1194e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1195e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1196e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1197e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1198e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1199e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1200e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1201e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1202e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1203e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1204e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1205e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1206e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1207e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1208e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1209e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
121019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
121119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
121219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
121319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1214e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1215e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
121619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
121719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
121819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
121919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1220e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1221e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1222e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1223e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1224e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1225e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1226e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
122719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
122819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1230e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
1231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ShiftReg = TryParseRegister();
1232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
123319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
123419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
123519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
123619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
123719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
123819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
124019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
124119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
124492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
124592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                                       ShiftReg, Imm,
12470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
124892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
124992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
125092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
12510082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
125219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
12530082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
12540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12550082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
125650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
125750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
125850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1259e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1260e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1261e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
126250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
126350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1264e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
1265e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int RegNo = TryParseRegister();
1266e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
126750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1268d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
126950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1270a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1271e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1272e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
127350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
127450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1275e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
127699e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
127799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
127850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1279a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1280a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1281fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1282fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1283fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1285e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1286e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1287e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1288e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1289e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1290fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1291e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1292e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1293e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1294e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1295e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1296e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1297e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1298e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1299e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1300e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1301e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1302e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1303e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1304e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1305e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1306e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1307fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1308e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1309e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1310e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1311e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1312e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1313e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1314e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1315e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1316e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1317e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1318e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1319e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1320e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1321e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1322e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1323e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1324f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1325fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1326fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1327f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1328f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1329e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1330e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1331e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1332e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1333fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1334e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1335f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1336e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1337e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1338fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1339f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1340fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1341fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1342f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1343fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1344fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1345f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1346f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1347fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1348fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1349fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1350fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1351fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1352fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1353f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1354fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1355fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1356fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1357f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1358e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1359e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1360c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1361c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
136250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
136350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
136418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1365a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1366e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
136716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
13687729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
13697729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
13705fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1371d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
13727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1373e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
13747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1375d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
137618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1377d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1378c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1379c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
138050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1381c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1382e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
13831d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling    int RegNum = TryParseRegister();
1384c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1385c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
138650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1387c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1388d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1389e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1390e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1391e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1392e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1393e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1394e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1395e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1396e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1397e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1398e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1399e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
14007729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
14017729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1402e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1403e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
140418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1405c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1406c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
140750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1408c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1409d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1410e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1411e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
141203f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1413e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
14145fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1415e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1416e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14177caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
14188e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
14198e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
14207caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
14217caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
14227caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1423e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
14247729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
14257caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1426e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14278e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1428e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
142950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1430e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1431e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14328e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1433e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1434e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1435e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14368e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
14378e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1438e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1439e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
144050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
144150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1442d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1443d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1444f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1445f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1446f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1447706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1448706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1449706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1450706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1451706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1452706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1453706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1454706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1455032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
1456706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1457032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
1458706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1459706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1460032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
1461706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1462032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
1463706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1464706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1465706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1466706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1467706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1468f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1469706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1470706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1471706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1472f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1473706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1474706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
14758bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1476a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1477a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1478a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1479a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1480a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1481a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1482a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1483a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1484a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1485a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1486a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1487a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1488a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1489a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1490a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1491a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1492a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1493a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1494a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1495a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1496a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1497a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1498a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1499a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1500a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1501a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1502584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1503584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1504584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1505584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1506584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1507584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1508584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1509584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1510584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1511584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1512584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1513584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1514584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1515b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
1516584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1517584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1518584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1519584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1520584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1521584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1522584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1523584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1524584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1525584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1526b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
1527584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1528584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1529584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1530584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
15314b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1532584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1533584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1534584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1535584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
15364b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1537584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
153856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
153956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1540584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1541584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1543584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1545584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1551584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1552584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1553584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1554584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1555584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1556584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1557584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1558584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1559584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1560584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1561584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1562584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1563584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1564584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1565584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1566584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1567584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1568a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1569a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1570ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1571ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1572ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1573e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1574ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1575ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode2))
1576ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return MatchOperand_NoMatch;
1577ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1578ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return MatchOperand_Success;
1579ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1580ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1581ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1582ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1583ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1584ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1585ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1586ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode3))
1587ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1588ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1589ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return MatchOperand_Success;
1590ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1591ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1592f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1593f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
1594f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
1595f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1596f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1597f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1598f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1599f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1600f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
1601f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
1602f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
1603f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
1604f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1605f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1606f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1607f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
1608f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1609f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
1610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1611f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
1615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
1617f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
1618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1619f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
1620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
1624f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
1625f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1626f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1627f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
1628f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
1629f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
1630f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1631f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1632f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1633f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
1634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
1636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
1637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1638ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1639ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1640ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1641ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1642ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1643ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1644ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1645ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1646ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1647ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1648ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1649ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1650ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1651ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1652ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1653ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1654ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1655ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1656ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1657ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1658ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1659ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1660ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1661ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1662ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1663ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1664ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1665ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1666ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1667ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1668ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1670ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1671ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1672ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1673ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1674ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1675ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1676ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1677ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1678ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1679ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1680ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1681ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1682ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1683ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1684ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1685ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1686ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1687ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1688ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1689ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1690ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1691ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1692ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1693ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1694ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1695ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1696ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1697ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1698e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
16999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
170050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling///
17019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
17029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
170350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
1704ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1705ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1706762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
170718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
1708a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
1709762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
1710b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
1711a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
171218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
1713550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1714550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
171550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1716550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1717e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int BaseRegNum = TryParseRegister();
1718e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (BaseRegNum == -1) {
1719550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
172050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1721550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1722a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17230571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
17240571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
17250571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
17260571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    return true;
17270571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
1728a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
1729a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
1730a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
1731a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
1732a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
173305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  ARMOperand *WBOp = 0;
173405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  int OffsetRegNum = -1;
173505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  bool OffsetRegShifted = false;
17360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
173705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *ShiftAmount = 0;
173805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *Offset = 0;
1739a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
17419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
1742a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
1743a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
1744b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
174505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1746550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1747550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
174850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
174918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
1750550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
1751550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
175250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1753550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
1754762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
1755b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1756a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
175718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
1758a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
1759ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      // None of addrmode3 instruction uses "!"
1760ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode3)
1761ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return true;
1762ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
176350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
176450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                     ExclaimTok.getLoc());
1765a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
1766b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
1767ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1768ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode2)
1769ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        Preindexed = false;
1770a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
17710571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  } else {
17720571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    // The "[Rn" we have so far was not followed by a comma.
17730571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
177480eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // If there's anything other than the right brace, this is a post indexing
177580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // addressing form.
1776762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
1777b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1778a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
177918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
178003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1781e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
178280eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Postindexed = true;
178380eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Writeback = true;
178450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1785550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
1786550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
178750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1788550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
178950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1790b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
179150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1792550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
179316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1794550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
179550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1796a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
179705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  }
1798e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
179905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  // Force Offset to exist if used.
180005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (!OffsetIsReg) {
180105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    if (!Offset)
180205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar      Offset = MCConstantExpr::Create(0, getContext());
1803ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  } else {
1804ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1805ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Error(E, "shift amount not supported");
1806ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
1807ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
1808a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
180905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1810ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1811ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Offset, OffsetRegNum, OffsetRegShifted,
1812ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     ShiftType, ShiftAmount, Preindexed,
1813ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Postindexed, Negative, Writeback, S, E));
181405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (WBOp)
181505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    Operands.push_back(WBOp);
181605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
181705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  return false;
1818a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1819a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
18209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
18219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
18229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
18239c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
18249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
18259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
18269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
18279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
18290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                        enum ARM_AM::ShiftOpc &ShiftType,
18309c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
18319c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
18329c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
1833762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
1834762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
18359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
18369c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
18379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
18389c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
183918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
1840762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
18419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
1842b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
18439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
18449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
1845b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
18469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
18479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
184818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
18499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
1850e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    SMLoc CurLoc = OffsetRegTok.getLoc();
1851e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    OffsetRegNum = TryParseRegister();
1852e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    if (OffsetRegNum != -1) {
1853550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
1854e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner      E = CurLoc;
1855762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
18569c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
1857d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
185812f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling  // If we parsed a register as the offset then there can be a shift after that.
18599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
18609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
186118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
18629c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
1863b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
18649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
186518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
1866762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
18673472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
18689c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
18699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
18709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
18719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
18729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
187318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
18749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
18759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
187616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1877b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
18789c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
18799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
18809c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
1881762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
18829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
18839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
18849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
18859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
1886a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
1887a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
1888a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
1889a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
18900082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
18910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                              const MCExpr *&ShiftAmount, SMLoc &E) {
189218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1893a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
1894a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
189538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
1896a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
18970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
1898a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
18990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
1900a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
19010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
1902a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
19030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
1904a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
19050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
1906a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
1907a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
1908b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
1909a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
19109c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
19110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (St == ARM_AM::rrx)
19129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
1913a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
19149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
191518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
19169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
19179c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
1918b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
19199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
19209c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
19219c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
1922a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1923a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
1924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1925a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
19269c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
19279c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
1928e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1929fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
1930762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
1931fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1932fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
1933fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
1934f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1935f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
1936fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
1937f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1938f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
1939f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
1940f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
1941f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
1942fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1943a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
1944146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
1945146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
194650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
194719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
194850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    if (!TryParseRegisterWithWriteBack(Operands))
194950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
195019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    int Res = TryParseShiftRegister(Operands);
195119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
19520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
195319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
195419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
1955e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1956e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
1957e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
195819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
195967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
196067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
1961515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
1962515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
1963515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
1964762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1965515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
196650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1967762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
196850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
196950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
197050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
1971a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
197250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseMemory(Operands);
1973d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
197450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseRegisterList(Operands);
1975d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
1976079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
1977079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1978762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1979b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
1980515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
1981515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
198250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1983762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
198450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
198550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
19869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
19879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
19887597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
19897597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
19907597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
19919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (ParsePrefix(RefKind))
19929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
19939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19947597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
19957597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
19969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
19979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
19987597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
19997597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
20009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
20017597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
20029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
20039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
2004a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2005a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2006a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
20077597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
20087597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
20097597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
20107597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
20119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
20138a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
20149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
20159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
20179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
20189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
20199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
20229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
20237597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
20249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
20257597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
20269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
20279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
20289081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
20299081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20309081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
20319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
20339081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
20349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
20359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
20379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
20389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
20399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
20419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
20429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
20439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
20449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
20459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
20469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
20479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
20499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
20509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
20519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
20529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
20539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
20559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
20569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
20589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
20599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
20619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
20649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
20659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
20679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
20689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
20699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
20709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
20719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
20729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
20749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
20769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
20779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
20789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
20799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
20809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
2081352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
2082352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
2083352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
2084badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
20855f16057d1e4b711d492091bc555693a03d4a1b6eJim GrosbachStringRef ARMAsmParser::SplitMnemonic(StringRef Mnemonic,
20865f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
20875f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
20885f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &ProcessorIMod) {
2089352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
2090352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
2091a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
2092352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2093badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
2094352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
2095352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
20965f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
20975f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
20985f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
20995f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
21005f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
21015f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
21025f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
21035f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
2104352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
2105badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
21063f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
21073f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
2108ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
2109ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach      Mnemonic != "muls") {
21103f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
21113f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
21123f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
21133f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
21143f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
21153f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
21163f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
21173f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
21183f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
21193f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
21203f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
21213f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
21223f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
21233f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
21243f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
21253f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
21263f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
21273f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
21283f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
21293f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
21303f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
21313f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
21323f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
213352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
2134345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2135352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
2136352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
2137352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
2138352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
21395f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
21405f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
21415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
21425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vrsqrts" || (Mnemonic == "movs" && isThumb()))) {
2143352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
2144352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
2145352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
2146352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2147a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
2148a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
2149a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
2150a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
2151a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
2152a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2153a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
2154a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
2155a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
2156a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
2157a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2158a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
2159a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
2160a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2161a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2162352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
2163352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
21643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
21653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
21663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
21673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
21683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
2169fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
2170fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2171fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
2172eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2173eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2174eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2175eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2176be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2177eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2178eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
2179be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "eor" || Mnemonic == "smlal" ||
2180ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
2181eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
2182eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
2183eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
2184eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
21853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
2186eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2187eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2188eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2189eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
21905f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
21915f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
21923771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
21933771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
21943771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
21953771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
2196fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
2197ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
2198fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
219963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2200fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
2201badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
2202badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2203badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
2204badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2205badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2206badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
2207badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
2208ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
2209badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2210352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
2211352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
2212a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
2213352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
2214ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting,
2215a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                       ProcessorIMod);
2216badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2217ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
2218ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2219ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
2220ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
22219717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
22223771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
22233771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
22243771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
22253771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
22263771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
22273771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
22283771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
22293771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
2230ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  GetMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
22313771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
223233c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
223333c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
223433c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
223533c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
2236ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
223733c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
223833c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
223933c16a27370939de39679245c3dff72383c210bdJim Grosbach
22403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
22413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
22423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
22433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
22443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
224533c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (CanAcceptCarrySet)
22463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
22473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
22483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
22493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
22503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
22513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
22523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
22533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
22543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a predication code, but the user wrote
22553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // one (or misspelled another mnemonic).
22563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
22573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
2258badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
2259345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2260a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
2261a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
2262a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
2263a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
2264a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
2265a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
2266a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
2267a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
2268a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2269a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
2270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2271a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2272345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
22735747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
22745747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
22755747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
2276a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
2277a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2278a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
22795747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
22805747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
22815747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
22825747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2283a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
2284ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (ParseOperand(Operands, Mnemonic)) {
2285cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
2286cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
2287cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
2288a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2289a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
2290b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
2291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
2293ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      if (ParseOperand(Operands, Mnemonic)) {
2294cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
2295cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
2296cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
2297a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
2298a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
229916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2300cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2301cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
230234e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
2303cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
2304146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
230534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
2306ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2307ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2308ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
2309ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
2310ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
2311ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // operand if that's the instruction we're trying to match.
2312ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  //
2313ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // We do this post-processing of the explicit operands rather than just
2314ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // conditionally adding the cc_out in the first place because we need
2315ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // to check the type of the parsed immediate operand.
2316ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  if (Mnemonic == "mov" && Operands.size() > 4 &&
2317ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
2318731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
2319731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0) {
2320ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
2321ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
2322ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
2323ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
2324ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2325ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2326ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
23279898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
2328ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2329ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2330fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
2331fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
2332fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2333fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
2334fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
2335fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
23365a18700470f0831b9b2af78862672561dd980345Jim Grosbach  MatchResultTy MatchResult;
2337193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2338193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2339e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2340fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2341fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2342e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2343e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2344e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2345e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2346e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2347e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2348e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2349e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
235016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2351e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2352e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2353e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
235416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2355e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2356e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2357e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2358e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2359b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2360b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2361fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
236216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2363c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2364146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2365fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2366fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
2367515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
2368ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2369ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2370ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
2371ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
2372515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
2373515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
2374515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
2375515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2376515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
2377515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
2378515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
2379515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
2380ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2381ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2382ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2383ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
2384ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
2385ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2386ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2387ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2388ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2389ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2390ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2391ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2392aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2393ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2394ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2395ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
239616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2397ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2398ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2399ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2400b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2401ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2402ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2403ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2404b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2405ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2406ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2407ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2408515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
2409515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
2410515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2411515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2412515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2413b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2414515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2415515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2416515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2417515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2418515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2419515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2420515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2421515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
2422515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
2423515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
24246469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
24256469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
24266469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
24276469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
24286469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
24296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
24306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
24316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
24326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
24336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
24346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
24356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
24366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
24376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2438515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2439515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2440b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2441515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
24426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
24436469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
24446469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
24456469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
24466469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2447642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2448642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2449642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2450515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2451515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2452515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2453515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
2454515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
2455515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
245618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2457515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2458515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
245938e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
246058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2461b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
246258c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
24639e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2464515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2465515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2466515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2467515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
246818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2469b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2470515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2471515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2472515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2473515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2474515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2475515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2476515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
2477515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
2478515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
247918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2480515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2481515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
248218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
248358c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2484b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
248558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2486b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2487515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2488515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2489515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2490515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
249118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2492b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2493515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
249432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
2495ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (!isThumb())
2496ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
24972a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
249832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
2499ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    if (isThumb())
2500ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
25012a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2502eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
25032a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2504515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2505515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2506515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
250790b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
250890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
25099c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2510ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
2511ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2512ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
251390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2514ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
25153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
25160692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
25170692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
25183483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2519