ARMAsmParser.cpp revision eb0caa115491019f7f7fe45fc70ad47682244187
1ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===-- ARMAsmParser.cpp - Parse ARM assembly to MCInst instructions ------===//
2ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
3ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//                     The LLVM Compiler Infrastructure
4ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
5ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// This file is distributed under the University of Illinois Open Source
6ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby// License. See LICENSE.TXT for details.
7ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//
8ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby//===----------------------------------------------------------------------===//
9ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
10ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "ARM.h"
1192b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling#include "ARMAddressingModes.h"
127597212abced110723f2fee985a7d60557c092ecEvan Cheng#include "ARMMCExpr.h"
13b72d2a92b75daa9cbac7338aff0cd8ae04c2b4bdEvan Cheng#include "ARMBaseRegisterInfo.h"
143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMSubtarget.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
16c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
17c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
186469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
19642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
21ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
22ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h"
25ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetAsmParser.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
27fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2875ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
34ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#define GET_SUBTARGETINFO_ENUM
35ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "ARMGenSubtargetInfo.inc"
36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyclass ARMAsmParser : public TargetAsmParser {
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
4532869205052430f45d598fba25ab878d8b29da2dEvan Cheng  /// STI, ARM_STI, Thumb_STI - Subtarget info for ARM and Thumb modes. STI
4632869205052430f45d598fba25ab878d8b29da2dEvan Cheng  /// points to either ARM_STI or Thumb_STI depending on the mode.
4732869205052430f45d598fba25ab878d8b29da2dEvan Cheng  const MCSubtargetInfo *STI;
4832869205052430f45d598fba25ab878d8b29da2dEvan Cheng  OwningPtr<const MCSubtargetInfo> ARM_STI;
4932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  OwningPtr<const MCSubtargetInfo> Thumb_STI;
50ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
51ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
52ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
53ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
54ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
55ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
56ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
57e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int TryParseRegister();
58bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
5950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool TryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
6150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
62ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &,
63ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   ARMII::AddrMode AddrMode);
64fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
657597212abced110723f2fee985a7d60557c092ecEvan Cheng  bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
69a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  bool ParseMemoryOffsetReg(bool &Negative,
719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetRegShifted,
720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                            enum ARM_AM::ShiftOpc &ShiftType,
739c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&ShiftAmount,
749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            const MCExpr *&Offset,
759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                            bool &OffsetIsReg,
76762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            int &OffsetRegNum,
77762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                            SMLoc &E);
780082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool ParseShift(enum ARM_AM::ShiftOpc &St,
790082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                  const MCExpr *&ShiftAmount, SMLoc &E);
80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool ParseDirectiveWord(unsigned Size, SMLoc L);
81515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumb(SMLoc L);
82515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveThumbFunc(SMLoc L);
83515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveCode(SMLoc L);
84515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  bool ParseDirectiveSyntax(SMLoc L);
85515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
867036f8be4df8a1a830ca01afe9497b035a5647d6Chris Lattner  bool MatchAndEmitInstruction(SMLoc IDLoc,
877c51a3172cf5104ebeaef22f1366fa634ca00d85Chris Lattner                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
88fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                               MCStreamer &Out);
89fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes  void GetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
90fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
9116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
94ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    return (STI->getFeatureBits() & ARM::ModeThumb) != 0;
95ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
96ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
97ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    return isThumb() && (STI->getFeatureBits() & ARM::FeatureThumb2) == 0;
98ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
9932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
10032869205052430f45d598fba25ab878d8b29da2dEvan Cheng    STI = isThumb() ? ARM_STI.get() : Thumb_STI.get();
10132869205052430f45d598fba25ab878d8b29da2dEvan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI->getFeatureBits()));
10232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
103ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
104a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
105a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1070692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1080692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
109a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
110a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
111a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocNumOperand(
113f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
114f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseCoprocRegOperand(
115f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
116f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy tryParseMemBarrierOptOperand(
1178bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
118a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  OperandMatchResultTy tryParseProcIFlagsOperand(
1198bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
120584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  OperandMatchResultTy tryParseMSRMaskOperand(
1218bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode2Operand(
123ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
124ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  OperandMatchResultTy tryParseMemMode3Operand(
125ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
126ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
127ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
128ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
129ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
130ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
131ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
132ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
133ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
134ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool CvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
135ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
136f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach
137ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
138480cee5d4396a380ada6ffd03551b5700d041fe0Evan Cheng  ARMAsmParser(StringRef TT, StringRef CPU, StringRef FS, MCAsmParser &_Parser)
13932869205052430f45d598fba25ab878d8b29da2dEvan Cheng    : TargetAsmParser(), Parser(_Parser) {
140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
14132869205052430f45d598fba25ab878d8b29da2dEvan Cheng
14232869205052430f45d598fba25ab878d8b29da2dEvan Cheng    STI = ARM_MC::createARMMCSubtargetInfo(TT, CPU, FS);
14332869205052430f45d598fba25ab878d8b29da2dEvan Cheng    // FIXME: Design a better way to create two subtargets with only difference
14432869205052430f45d598fba25ab878d8b29da2dEvan Cheng    // being a feature change.
14532869205052430f45d598fba25ab878d8b29da2dEvan Cheng    if (isThumb()) {
14632869205052430f45d598fba25ab878d8b29da2dEvan Cheng      Thumb_STI.reset(STI);
14732869205052430f45d598fba25ab878d8b29da2dEvan Cheng      assert(TT.startswith("thumb") && "Unexpected Triple string for Thumb!");
14832869205052430f45d598fba25ab878d8b29da2dEvan Cheng      Twine ARM_TT = "arm" + TT.substr(5);
14932869205052430f45d598fba25ab878d8b29da2dEvan Cheng      ARM_STI.reset(ARM_MC::createARMMCSubtargetInfo(ARM_TT.str(), CPU, FS));
15032869205052430f45d598fba25ab878d8b29da2dEvan Cheng    } else {
15132869205052430f45d598fba25ab878d8b29da2dEvan Cheng      ARM_STI.reset(STI);
15232869205052430f45d598fba25ab878d8b29da2dEvan Cheng      assert(TT.startswith("arm") && "Unexpected Triple string for ARM!");
15332869205052430f45d598fba25ab878d8b29da2dEvan Cheng      Twine Thumb_TT = "thumb" + TT.substr(3);
15432869205052430f45d598fba25ab878d8b29da2dEvan Cheng      Thumb_STI.reset(ARM_MC::createARMMCSubtargetInfo(Thumb_TT.str(),CPU, FS));
15532869205052430f45d598fba25ab878d8b29da2dEvan Cheng    }
15632869205052430f45d598fba25ab878d8b29da2dEvan Cheng
157ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
158ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI->getFeatureBits()));
159ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
160ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
16138e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
1629898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner                                SmallVectorImpl<MCParsedAsmOperand*> &Operands);
163ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  virtual bool ParseDirective(AsmToken DirectiveID);
164ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
16516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
16616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1673a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1683a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
169a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
171146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
172762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1738462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
174d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
175fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
176fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
177cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
178706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1798462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
180584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
181a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1828462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1838d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
1860082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Shifter,
1878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
189a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
190762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
19124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
192a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
193a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
194a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1968462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1978462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
199706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
200706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
201706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
202706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
203fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
204fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
205fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
206fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
207a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
208a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
209a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
210a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
211584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
212584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
213584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
214584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
217a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
218a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
219a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
220a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
221a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
222a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2238155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
224cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
225cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
22616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2276a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
228a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
229ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARMII::AddrMode AddrMode;
230a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2312637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      union {
2322637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        unsigned RegNum;     ///< Offset register num, when OffsetIsReg.
2332637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar        const MCExpr *Value; ///< Offset value, when !OffsetIsReg.
2342637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      } Offset;
235146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      const MCExpr *ShiftAmount;     // used when OffsetRegShifted is true
2360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      enum ARM_AM::ShiftOpc ShiftType; // used when OffsetRegShifted is true
237146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling      unsigned OffsetRegShifted : 1; // only used when OffsetIsReg is true
23850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Preindexed       : 1;
23950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Postindexed      : 1;
24050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned OffsetIsReg      : 1;
24150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Negative         : 1; // only used when OffsetIsReg is true
24250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      unsigned Writeback        : 1;
243a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
2470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      unsigned RegNum;
2480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    } Shift;
249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
25016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
251146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
252146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
253762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
254762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
255762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
256762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2588462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2608462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
261762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
263762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
264d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2688d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2690f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2700f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
27124d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2728d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
273fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
274fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
275fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
276fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
279762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
280706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
281706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
282706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
283762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
284762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
285762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
289a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
290a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
2910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
2920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    case Shifter:
2930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      Shift = o.Shift;
2940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
29716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
298762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
299762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
300762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
301762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
302a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3038462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
3048462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
3058462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
3068462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
3078462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
308fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
309fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
310fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
311fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
312fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
313a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
314a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
315a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
318a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3196aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3207729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
321a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
322a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3235fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3240f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3250f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
32624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3278d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3288d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
329cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
330cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
331cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
332cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
333cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
334706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
335706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
336706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
337706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
338706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
339a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
340a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
341a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
342a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
343a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
344584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
345584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
346584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
347584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
348584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
3496ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @name Memory Operand Accessors
3506ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @{
351ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ARMII::AddrMode getMemAddrMode() const {
352ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return Mem.AddrMode;
353ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
3546ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemBaseRegNum() const {
3556ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.BaseRegNum;
3566ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3576ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegNum() const {
3586ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3596ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.RegNum;
3606ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3616ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemOffset() const {
3626ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(!Mem.OffsetIsReg && "Invalid access!");
3636ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.Offset.Value;
3646ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3656ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  unsigned getMemOffsetRegShifted() const {
3666ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && "Invalid access!");
3676ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.OffsetRegShifted;
3686ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3696ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  const MCExpr *getMemShiftAmount() const {
3706ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3716ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftAmount;
3726ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc getMemShiftType() const {
3746ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    assert(Mem.OffsetIsReg && Mem.OffsetRegShifted && "Invalid access!");
3756ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    return Mem.ShiftType;
3766ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  }
3776ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPreindexed() const { return Mem.Preindexed; }
3786ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemPostindexed() const { return Mem.Postindexed; }
3796ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemOffsetIsReg() const { return Mem.OffsetIsReg; }
3806ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemNegative() const { return Mem.Negative; }
3816ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  bool getMemWriteback() const { return Mem.Writeback; }
3826ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
3836ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar  /// @}
3846ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar
385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
386fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3878462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
388d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
3906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
3916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
3926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
3936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3946b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
3956b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
3966b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
3976b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
3986b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
3996b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4006b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4016b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4026b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4036b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4046b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
4056b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
406b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
4078d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
4080f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
4090f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
41014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
411706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
41214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
4130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  bool isShifter() const { return Kind == Shifter; }
414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  bool isMemMode2() const {
415ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode2)
416ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
417ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
418ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg())
419ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return true;
420ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
421ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemNegative() &&
422ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
426ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (!CE) return false;
427ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Value = CE->getValue();
428ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
429ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // The offset must be in the range 0-4095 (imm12).
430ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Value > 4095 || Value < -4095)
431ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
432ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
433ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return true;
434ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
435ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  bool isMemMode3() const {
436ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemAddrMode() != ARMII::AddrMode3)
437ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
438ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
439ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
440ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (getMemOffsetRegShifted())
441ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return false; // No shift with offset reg allowed
442ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
443ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
444ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
445ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemNegative() &&
446ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        !(getMemPostindexed() || getMemPreindexed()))
447ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
448ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
449ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
450ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (!CE) return false;
451ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Value = CE->getValue();
452ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
453ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // The offset must be in the range 0-255 (imm8).
454ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Value > 255 || Value < -255)
455ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
456ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
457ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
458ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
45987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  bool isMemMode5() const {
4604b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback() ||
4614b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar        getMemNegative())
46287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
463ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4644b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
465ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
466ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
46787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    // The offset must be a multiple of 4 in the range 0-1020.
46887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    int64_t Value = CE->getValue();
46987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling    return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
47087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
471505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  bool isMemMode7() const {
472505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!isMemory() ||
473505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPreindexed() ||
474505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemPostindexed() ||
475505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemOffsetIsReg() ||
476505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemNegative() ||
477505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes        getMemWriteback())
478505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
479505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
480505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
481505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (!CE) return false;
482505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
483505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    if (CE->getValue())
484505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes      return false;
485505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
486505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
487505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
488f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeRegThumb() const {
4894b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || !getMemOffsetIsReg() || getMemWriteback())
490f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
491d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    return true;
492f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
493f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  bool isMemModeImmThumb() const {
4944b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    if (!isMemory() || getMemOffsetIsReg() || getMemWriteback())
495ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
496ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
4974b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
498ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
499ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
500ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    // The offset must be a multiple of 4 in the range 0-124.
501ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    uint64_t Value = CE->getValue();
502ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    return ((Value & 0x3) == 0 && Value <= 124);
503ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
504584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
505a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
5063483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5073483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
50814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
50914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
51014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
51114b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
5123483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
5133483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
5143483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
5153483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
5163483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5178462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
518345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
5198462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
52004f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
52104f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
5228462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
5238462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
524fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
525fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
526fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
527fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
528fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
529fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
530fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
531fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
532fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
533fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
534d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
535d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
536d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
537d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
538d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
539a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
540a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
543a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
5440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  void addShifterOperands(MCInst &Inst, unsigned N) const {
5450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
5460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
5470082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      ARM_AM::getSORegOpc(Shift.ShiftTy, 0)));
5480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
5490082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
55087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
5517729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
5525fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
5535fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
5547729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
5557729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
55687f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
55787f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
5580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
5590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5600f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5610f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5620f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
5630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
5640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
5650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
5663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
5676b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
5686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
5696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
5706b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
5716b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
5726b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
5736b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
5746b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
5756b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
5766b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
5773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
5783483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
5793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
58016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
581706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
582706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
583706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
584706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
585706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
586505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  void addMemMode7Operands(MCInst &Inst, unsigned N) const {
587505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert(N == 1 && isMemMode7() && "Invalid number of operands!");
588505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
589505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
590505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
5911866af4a982be999e4d0c08c38ebec71f3ed4025Matt Beaumont-Gay    (void)CE;
592505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    assert((CE || CE->getValue() == 0) &&
593505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes           "No offset operand support in mode 7");
594505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
595505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
596ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  void addMemMode2Operands(MCInst &Inst, unsigned N) const {
597ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(isMemMode2() && "Invalid mode or number of operands!");
598ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
599ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
600ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
601ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (getMemOffsetIsReg()) {
602ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
603ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
604ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
605ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      ARM_AM::ShiftOpc ShOpc = ARM_AM::no_shift;
606ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      int64_t ShiftAmount = 0;
607ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
608ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (getMemOffsetRegShifted()) {
609ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShOpc = getMemShiftType();
610ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        const MCConstantExpr *CE =
611ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                   dyn_cast<MCConstantExpr>(getMemShiftAmount());
612ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        ShiftAmount = CE->getValue();
613ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      }
614ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
615ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(AMOpc, ShiftAmount,
616ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           ShOpc, IdxMode)));
617ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return;
618ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
619ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
620ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
621ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
622ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
623ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
624ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    // the difference?
625ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
626ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    assert(CE && "Non-constant mode 2 offset operand!");
627ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    int64_t Offset = CE->getValue();
628ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
629ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    if (Offset >= 0)
630ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::add,
631ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                           Offset, ARM_AM::no_shift, IdxMode)));
632ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    else
633ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM2Opc(ARM_AM::sub,
634ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                          -Offset, ARM_AM::no_shift, IdxMode)));
635ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
636ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
637ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  void addMemMode3Operands(MCInst &Inst, unsigned N) const {
638ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(isMemMode3() && "Invalid mode or number of operands!");
639ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
640ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    unsigned IdxMode = (getMemPreindexed() | getMemPostindexed() << 1);
641ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
642ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (getMemOffsetIsReg()) {
643ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
644ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
645ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      ARM_AM::AddrOpc AMOpc = getMemNegative() ? ARM_AM::sub : ARM_AM::add;
646ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(AMOpc, 0,
647ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                                             IdxMode)));
648ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return;
649ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
650ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
651ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // Create a operand placeholder to always yield the same number of operands.
652ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateReg(0));
653ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
654ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
655ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    // the difference?
656ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
657ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    assert(CE && "Non-constant mode 3 offset operand!");
658ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    int64_t Offset = CE->getValue();
659ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
660ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (Offset >= 0)
661ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::add,
662ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           Offset, IdxMode)));
663ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    else
664ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM3Opc(ARM_AM::sub,
665ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                                           -Offset, IdxMode)));
666ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
667ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
66814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  void addMemMode5Operands(MCInst &Inst, unsigned N) const {
66914b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    assert(N == 2 && isMemMode5() && "Invalid number of operands!");
67016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
6714b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6724b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    assert(!getMemOffsetIsReg() && "Invalid mode 5 operand");
67392b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
67480eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // FIXME: #-0 is encoded differently than #0. Does the parser preserve
67580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // the difference?
6764b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
677d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert(CE && "Non-constant mode 5 offset operand!");
678d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
679d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // The MCInst offset operand doesn't include the low two bits (like
680d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    // the instruction encoding).
681d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    int64_t Offset = CE->getValue() / 4;
682d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    if (Offset >= 0)
683d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
684d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             Offset)));
685d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    else
686d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
687d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar                                                             -Offset)));
68814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
6893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
690f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
691f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
6924b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6934b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemOffsetRegNum()));
694f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
695ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
696f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
697f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
6984b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    Inst.addOperand(MCOperand::CreateReg(getMemBaseRegNum()));
6994b462672d2b4950e5f059bd093db524aa10e8377Daniel Dunbar    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getMemOffset());
700f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    assert(CE && "Non-constant mode offset operand!");
701f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
702ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
703ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
704584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
705584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
706584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
707584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
708584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
709a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
710a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
711a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
712a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
713a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
714fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  virtual void dump(raw_ostream &OS) const;
715b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
7163a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
7173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
718345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
719345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
720345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
7213a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
722345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
723345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
724fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
725fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
726fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
727fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
728fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
730fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
731fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
732fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
733fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
735fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
738fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
740d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
741d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
742d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
743d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
744d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
745d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
746d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
747d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
7483a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
7493a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
750762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
751762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
752762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
753762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
7543a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
755a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
756a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
75750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
7583a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
759762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
760762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
761762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
7623a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
763a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
764a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
7650082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
7660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
7670082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    ARMOperand *Op = new ARMOperand(Shifter);
7680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->Shift.ShiftTy = ShTy;
7690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
7700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
7710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
7720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
7730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
7747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
7755fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
776cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
7770f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
7780f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7790f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    if (ARM::DPRRegClass.contains(Regs.front().first))
7800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
7810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    else if (ARM::SPRRegClass.contains(Regs.front().first))
7820f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
7830f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
7840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
7855fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
7867729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
78724d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
788cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
789cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
790cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
7918d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
7928d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
7938d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
7943a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
7953a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
796762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
797762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
798762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
7993a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
800cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
801cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
802ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  static ARMOperand *CreateMem(ARMII::AddrMode AddrMode, unsigned BaseRegNum,
803ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               bool OffsetIsReg, const MCExpr *Offset,
804ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                               int OffsetRegNum, bool OffsetRegShifted,
8050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               enum ARM_AM::ShiftOpc ShiftType,
8063a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               const MCExpr *ShiftAmount, bool Preindexed,
8073a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               bool Postindexed, bool Negative, bool Writeback,
8083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
809023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((OffsetRegNum == -1 || OffsetIsReg) &&
810023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegNum must imply OffsetIsReg!");
811023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!OffsetRegShifted || OffsetIsReg) &&
812023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "OffsetRegShifted must imply OffsetIsReg!");
813d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar    assert((Offset || OffsetIsReg) &&
814d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar           "Offset must exists unless register offset is used!");
815023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!ShiftAmount || (OffsetIsReg && OffsetRegShifted)) &&
816023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have shift amount without shifted register offset!");
817023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar    assert((!Offset || !OffsetIsReg) &&
818023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar           "Cannot have expression offset and register offset!");
819023835d51b6dd6e3a253deefa595b0d916b605acDaniel Dunbar
8203a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
821ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    Op->Mem.AddrMode = AddrMode;
822762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
823762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetIsReg = OffsetIsReg;
8242637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    if (OffsetIsReg)
8252637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.RegNum = OffsetRegNum;
8262637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar    else
8272637dc9a252f25fd1c63acfe0606860ee7c8cfdfDaniel Dunbar      Op->Mem.Offset.Value = Offset;
828762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.OffsetRegShifted = OffsetRegShifted;
829762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
830762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftAmount = ShiftAmount;
831762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Preindexed = Preindexed;
832762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Postindexed = Postindexed;
833762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Negative = Negative;
834762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.Writeback = Writeback;
83516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
836762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
837762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
8383a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
839a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
840706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
841706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
842706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
843706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
844706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
845706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
846706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
847706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
848a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
849a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
850a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
851a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
852a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
853a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
854a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
855a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
856584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
857584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
858584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
859584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
860584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
861584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
862584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
863584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
864a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
865a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
866a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
867a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
868fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbarvoid ARMOperand::dump(raw_ostream &OS) const {
869fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
870fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
8716a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
872fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
873d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
874d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
875d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
876fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
877fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
878fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
879fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
880fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
881fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
882584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
883584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
884584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
885fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
886fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
887fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
888706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
889706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
890706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
891fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
8926ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
893ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << "am:" << ARMII::AddrModeToString(getMemAddrMode())
894ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes       << " base:" << getMemBaseRegNum();
8956ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg()) {
8966ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:<register " << getMemOffsetRegNum();
8976ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      if (getMemOffsetRegShifted()) {
8986ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-type:" << getMemShiftType();
8996ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar        OS << " offset-shift-amount:" << *getMemShiftAmount();
9006ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      }
9016ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    } else {
9026ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " offset:" << *getMemOffset();
9036ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    }
9046ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemOffsetIsReg())
9056ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (offset-is-reg)";
9066ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPreindexed())
9076ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (pre-indexed)";
9086ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemPostindexed())
9096ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (post-indexed)";
9106ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemNegative())
9116ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (negative)";
9126ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    if (getMemWriteback())
9136ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar      OS << " (writeback)";
9146ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
915fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
916a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
918a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
919a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
920a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
921a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
922a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
923a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
924a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
925fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
92650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
927fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
9280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  case Shifter:
9290082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    OS << "<shifter " << getShiftOpcStr(Shift.ShiftTy) << ">";
9300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
9310f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
9320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
9330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
9348d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
9358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
9365fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
9375fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
9387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
9397729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
9407729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
9418d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
9428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
9438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
9448d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
9458d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
946fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
947fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
948fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
949fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
950fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
9513483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9523483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
9533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
9543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
9563483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
9573483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
9583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
95969df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
96069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
961bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  RegNo = TryParseRegister();
962bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
963bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
964bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
965bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
9669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
967e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
968e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
9693a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
970e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattnerint ARMAsmParser::TryParseRegister() {
97118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
972a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
973d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
974a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
975a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
9760c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
9770c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
9780c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
9790c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
9800c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
9810c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
9820c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
9830c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
9840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
9850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
9860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
9870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
98869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
989b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
990e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
991e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
992d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
9930082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// Try to parse a register name.  The token must be an Identifier when called,
9940082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// and if it is a register name the token is eaten and the register number is
9950082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson/// returned.  Otherwise return -1.
9960082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson///
9970082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::TryParseShiftRegister(
9980082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
9990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
10000082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
10010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
10020082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
10040082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
10050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
10060082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
10070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
10080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
10090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
10100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
10110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
10120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
10140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return true;
10150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  Parser.Lex(); // Eat shift-type operand;
10170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  int RegNum = TryParseRegister();
10180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (RegNum == -1)
10190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Error(Parser.getTok().getLoc(), "register expected");
10200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  Operands.push_back(ARMOperand::CreateReg(RegNum,S, Parser.getTok().getLoc()));
10220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  Operands.push_back(ARMOperand::CreateShifter(ShiftTy,
10230082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
10240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10250082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  return false;
10260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
10270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
10280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
102950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
103050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
103150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1032e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1033e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1034e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
103550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
103650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingTryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1037e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
1038e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int RegNo = TryParseRegister();
1039e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
104050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1041d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
104250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1043a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1044e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1045e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
104650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
104750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1048e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
104999e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
105099e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
105150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1052a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1053a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1054fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1055fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1056fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1057fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1058e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1059e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1060e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1061e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1062e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1063fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1064e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1065e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1066e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1067e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1068e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1069e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1070e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1071e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1072e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1073e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1074e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1075e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1076e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1077e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1078e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1079e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1080fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1081e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1082e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1083e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1084e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1085e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1086e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1087e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1088e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1089e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1090e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1091e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1092e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1093e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1094e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1095e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1096e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1097f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocNumOperand - Try to parse an coprocessor number operand. The
1098fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1099fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1100f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1101f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1102e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1103e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1104e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1105e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1106fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1107e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1108f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1109e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1110e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1111fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1112f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1113fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1114fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1115f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseCoprocRegOperand - Try to parse an coprocessor register operand. The
1116fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1117fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1118f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1119f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1120fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1121fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1122fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1123fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1124fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1125fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1126f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1127fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1128fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1129fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1130f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1131e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1132e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1133c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1134c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
113550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
113650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill WendlingParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
113718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1138a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1139e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
114016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
11417729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
11427729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
11435fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1144d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
11457729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1146e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
11477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1148d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
114918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1150d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1151c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1152c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
115350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1154c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1155e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
11561d6a26507bfd75758f5c8a29bccf577784ead751Bill Wendling    int RegNum = TryParseRegister();
1157c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1158c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
115950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1160c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1161d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1162e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1163e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1164e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1165e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1166e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1167e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1168e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1169e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1170e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1171e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1172e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
11737729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
11747729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1175e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1176e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
117718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1178c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1179c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
118050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1181c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1182d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1183e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1184e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
118503f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1186e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
11875fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1188e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1189e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
11907caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
11918e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
11928e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
11937caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
11947caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
11957caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1196e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
11977729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
11987caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1199e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12008e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1201e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
120250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1203e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1204e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12058e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1206e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1207e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1208e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
12098e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
12108e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1211e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1212e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
121350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
121450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1215d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1216d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1217f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach/// tryParseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1218f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1219f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachtryParseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1220706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1221706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1222706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1223706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1224706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1225706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1226706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1227706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1228706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1229706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1230706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1231706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1232706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1233706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1234706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1235706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1236706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1237f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1238706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1239706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1240706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1241f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1242706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1243706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
12448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes/// tryParseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1245a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1246a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopestryParseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1247a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1248a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1249a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1250a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1251a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1252a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1253a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1254a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1255a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1256a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1257a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1258a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1259a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1260a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1261a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1262a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1263a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1264a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1265a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1266a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1267a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1268a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1269a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1270a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1271584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1272584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1273584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes/// tryParseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1274584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1275584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopestryParseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1276584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1277584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1278584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1279584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1280584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1281584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1282584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1283584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1284584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef SpecReg = Mask.slice(Start, Next);
1285584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1286584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1287584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1288584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1289584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1290584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1291584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1292584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1293584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1294584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1295584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvq",  0x8) // same as CPSR_c
1296584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1297584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1298584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1299584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
13004b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1303584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1304584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
13054b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1306584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
130756926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
130856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1309584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1310584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1311584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1312584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1313584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1314584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1315584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1316584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1317584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1318584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1319584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1320584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1321584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1322584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1323584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1324584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1325584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1326584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1327584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1328584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1329584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1330584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1331584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1332584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1333584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1334584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1335584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1336584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1337a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1338a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1339ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// tryParseMemMode2Operand - Try to parse memory addressing mode 2 operand.
1340ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1341ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopestryParseMemMode2Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1342e3662cca5d204a3e0bceaead1b35361117630fabMatt Beaumont-Gay  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1343ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1344ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode2))
1345ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    return MatchOperand_NoMatch;
1346ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1347ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return MatchOperand_Success;
1348ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1349ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1350ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// tryParseMemMode3Operand - Try to parse memory addressing mode 3 operand.
1351ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
1352ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopestryParseMemMode3Operand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1353ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  assert(Parser.getTok().is(AsmToken::LBrac) && "Token is not a \"[\"");
1354ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1355ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  if (ParseMemory(Operands, ARMII::AddrMode3))
1356ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1357ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1358ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return MatchOperand_Success;
1359ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1360ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1361ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1362ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1363ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1364ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1365ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1366ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1367ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1368ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1369ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1370ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1371ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1372ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1373ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1374ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1375ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1376ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1377ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// CvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1378ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1379ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1380ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
1381ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesCvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1382ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1383ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1384ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1385ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1386ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode2Operands(Inst, 3);
1387ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1388ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1389ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1390ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1391ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1392ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1393ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1394ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1395ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1396ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1397ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1398ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1399ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1400ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1401ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1402ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1403ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1404ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1405ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1406ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1407ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// CvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
1408ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1409ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1410ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
1411ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso LopesCvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1412ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1413ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1414ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1415ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1416ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[3])->addMemMode3Operands(Inst, 3);
1417ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1418ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1419ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1420ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
1421e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
14229c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
142350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling///
14249c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// TODO Only preindexing and postindexing addressing are started, unindexed
14259c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// with option, etc are still to do.
142650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
1427ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso LopesParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1428ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes            ARMII::AddrMode AddrMode = ARMII::AddrModeNone) {
1429762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
143018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
1431a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
1432762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
1433b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
1434a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
143518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
1436550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  if (BaseRegTok.isNot(AsmToken::Identifier)) {
1437550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
143850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1439550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1440e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  int BaseRegNum = TryParseRegister();
1441e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (BaseRegNum == -1) {
1442550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    Error(BaseRegTok.getLoc(), "register expected");
144350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1444550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner  }
1445a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14460571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
14470571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
14480571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
14490571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    return true;
14500571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
1451a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Preindexed = false;
1452a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Postindexed = false;
1453a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool OffsetIsReg = false;
1454a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Negative = false;
1455a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  bool Writeback = false;
145605d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  ARMOperand *WBOp = 0;
145705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  int OffsetRegNum = -1;
145805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  bool OffsetRegShifted = false;
14590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  enum ARM_AM::ShiftOpc ShiftType = ARM_AM::lsl;
146005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *ShiftAmount = 0;
146105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  const MCExpr *Offset = 0;
1462a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
14639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // First look for preindexed address forms, that is after the "[Rn" we now
14649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // have to see if the next token is a comma.
1465a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.is(AsmToken::Comma)) {
1466a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Preindexed = true;
1467b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat comma token.
146805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1469550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
1470550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                             Offset, OffsetIsReg, OffsetRegNum, E))
147150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
147218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RBracTok = Parser.getTok();
1473550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    if (RBracTok.isNot(AsmToken::RBrac)) {
1474550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      Error(RBracTok.getLoc(), "']' expected");
147550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1476550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner    }
1477762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = RBracTok.getLoc();
1478b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1479a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
148018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &ExclaimTok = Parser.getTok();
1481a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    if (ExclaimTok.is(AsmToken::Exclaim)) {
1482ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      // None of addrmode3 instruction uses "!"
1483ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode3)
1484ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes        return true;
1485ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
148650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      WBOp = ARMOperand::CreateToken(ExclaimTok.getString(),
148750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                     ExclaimTok.getLoc());
1488a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      Writeback = true;
1489b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat exclaim token
1490ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    } else { // In addressing mode 2, pre-indexed mode always end with "!"
1491ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      if (AddrMode == ARMII::AddrMode2)
1492ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes        Preindexed = false;
1493a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
14940571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  } else {
14950571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar    // The "[Rn" we have so far was not followed by a comma.
14960571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
149780eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // If there's anything other than the right brace, this is a post indexing
149880eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach    // addressing form.
1499762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
1500b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
1501a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
150218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &NextTok = Parser.getTok();
150303f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1504e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby    if (NextTok.isNot(AsmToken::EndOfStatement)) {
150580eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Postindexed = true;
150680eb233a3ce1a6f2e6c0847cb3e456d735e37569Jim Grosbach      Writeback = true;
150750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1508550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (NextTok.isNot(AsmToken::Comma)) {
1509550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner        Error(NextTok.getLoc(), "',' expected");
151050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1511550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      }
151250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1513b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
151450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
1515550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
151616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach                               ShiftAmount, Offset, OffsetIsReg, OffsetRegNum,
1517550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner                               E))
151850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling        return true;
1519a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
152005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  }
1521e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
152205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  // Force Offset to exist if used.
152305d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (!OffsetIsReg) {
152405d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    if (!Offset)
152505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar      Offset = MCConstantExpr::Create(0, getContext());
1526ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  } else {
1527ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    if (AddrMode == ARMII::AddrMode3 && OffsetRegShifted) {
1528ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      Error(E, "shift amount not supported");
1529ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return true;
1530ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    }
1531a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
153205d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
1533ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMem(AddrMode, BaseRegNum, OffsetIsReg,
1534ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Offset, OffsetRegNum, OffsetRegShifted,
1535ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     ShiftType, ShiftAmount, Preindexed,
1536ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                     Postindexed, Negative, Writeback, S, E));
153705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  if (WBOp)
153805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar    Operands.push_back(WBOp);
153905d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
154005d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar  return false;
1541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
15439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse the offset of a memory operand after we have seen "[Rn," or "[Rn],"
15449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we will parse the following (were +/- means that a plus or minus is
15459c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// optional):
15469c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm
15479c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   +/-Rm, shift
15489c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby///   #offset
15499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// we return false on success or an error otherwise.
15509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderbybool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
1551762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        bool &OffsetRegShifted,
15520082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                        enum ARM_AM::ShiftOpc &ShiftType,
15539c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&ShiftAmount,
15549c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        const MCExpr *&Offset,
15559c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby                                        bool &OffsetIsReg,
1556762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        int &OffsetRegNum,
1557762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan                                        SMLoc &E) {
15589c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  Negative = false;
15599c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegShifted = false;
15609c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetIsReg = false;
15619c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  OffsetRegNum = -1;
156218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &NextTok = Parser.getTok();
1563762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  E = NextTok.getLoc();
15649c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (NextTok.is(AsmToken::Plus))
1565b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat plus token.
15669c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else if (NextTok.is(AsmToken::Minus)) {
15679c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    Negative = true;
1568b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat minus token
15699c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
15709c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // See if there is a register following the "[Rn," or "[Rn]," we have so far.
157118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &OffsetRegTok = Parser.getTok();
15729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegTok.is(AsmToken::Identifier)) {
1573e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    SMLoc CurLoc = OffsetRegTok.getLoc();
1574e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    OffsetRegNum = TryParseRegister();
1575e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    if (OffsetRegNum != -1) {
1576550276ee5bb3e115d4d81156dceffb9d3d78823aChris Lattner      OffsetIsReg = true;
1577e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner      E = CurLoc;
1578762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
15799c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
1580d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
158112f40e9a6305fe7553ebce19346cb55874073fc7Bill Wendling  // If we parsed a register as the offset then there can be a shift after that.
15829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (OffsetRegNum != -1) {
15839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for a comma then a shift
158418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &Tok = Parser.getTok();
15859c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (Tok.is(AsmToken::Comma)) {
1586b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex(); // Eat comma token.
15879c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
158818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan      const AsmToken &Tok = Parser.getTok();
1589762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      if (ParseShift(ShiftType, ShiftAmount, E))
15903472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        return Error(Tok.getLoc(), "shift expected");
15919c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      OffsetRegShifted = true;
15929c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    }
15939c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
15949c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
15959c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    // Look for #offset following the "[Rn," or "[Rn],"
159618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &HashTok = Parser.getTok();
15979c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (HashTok.isNot(AsmToken::Hash))
15989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby      return Error(HashTok.getLoc(), "'#' expected");
159916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1600b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat hash token.
16019c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
16029c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    if (getParser().ParseExpression(Offset))
16039c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby     return true;
1604762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
16059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
16069c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
16079c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
16089c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
1609a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ParseShift as one of these two:
1610a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
1611a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
1612a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// and returns true if it parses a shift otherwise it returns false.
16130082830cb26248178fe5cc9bbdbd00881556c33dOwen Andersonbool ARMAsmParser::ParseShift(ARM_AM::ShiftOpc &St,
16140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                              const MCExpr *&ShiftAmount, SMLoc &E) {
161518b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
1616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
1617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
161838e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
1619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
16200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
1621a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
16220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
1623a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
16240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
1625a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
16260082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
1627a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
16280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
1629a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
1630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
1631b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
1632a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
16339c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Rrx stands alone.
16340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (St == ARM_AM::rrx)
16359c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return false;
1636a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
16379c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  // Otherwise, there must be a '#' and a shift amount.
163818b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &HashTok = Parser.getTok();
16399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (HashTok.isNot(AsmToken::Hash))
16409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return Error(HashTok.getLoc(), "'#' expected");
1641b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat hash token.
16429c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
16439c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  if (getParser().ParseExpression(ShiftAmount))
16449c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby    return true;
1645a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1646a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
1647a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1648a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
16499c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
16509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
1651e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Andersonbool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1652fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
1653762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
1654fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1655fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
1656fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
1657f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1658f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
1659fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
1660f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1661f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
1662f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
1663f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
1664f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
1665fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1666a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
1667146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
1668146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
166950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
167067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Identifier:
167150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    if (!TryParseRegisterWithWriteBack(Operands))
167250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
16730082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    if (!TryParseShiftRegister(Operands))
16740082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
16750082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1676e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1677e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
1678e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
167967b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
168067b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
1681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
1682515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
1683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
1684762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1685515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
168650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1687762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
168850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
168950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
169050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
1691a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
169250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseMemory(Operands);
1693d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
169450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return ParseRegisterList(Operands);
1695d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
1696079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
1697079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
1698762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
1699b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
1700515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
1701515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
170250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1703762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
170450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
170550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
17069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
17079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
17087597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
17097597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
17107597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
17119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (ParsePrefix(RefKind))
17129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
17139081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17147597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
17157597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
17169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
17179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17187597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
17197597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
17209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
17217597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
17229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
17239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
1724a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1725a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1726a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
17277597212abced110723f2fee985a7d60557c092ecEvan Cheng// ParsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
17287597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
17297597212abced110723f2fee985a7d60557c092ecEvan Chengbool ARMAsmParser::ParsePrefix(ARMMCExpr::VariantKind &RefKind) {
17307597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
17319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
17338a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
17349081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
17359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
17379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
17389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
17399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
17429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
17437597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
17449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
17457597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
17469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
17479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
17489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
17499081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
17519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
17539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
17549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
17559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
17579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
17589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
17599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
17619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W KimARMAsmParser::ApplyPrefixToExpr(const MCExpr *E,
17629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
17639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
17649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
17659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
17669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
17679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
17699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
17709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
17719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
17729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
17739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
17759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
17769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
17789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
17799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
17819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
17849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
17859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
17879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
17889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *LHS = ApplyPrefixToExpr(BE->getLHS(), Variant);
17899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
17909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
17919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
17929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
17949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
17969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
17979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
17989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
17999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
18009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
1801352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
1802352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
1803352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
1804badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
1805a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopesstatic StringRef SplitMnemonic(StringRef Mnemonic,
1806a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &PredicationCode,
1807a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               bool &CarrySetting,
1808a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                               unsigned &ProcessorIMod) {
1809352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
1810352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
1811a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
1812352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1813badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
1814352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
1815352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
18168ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar  if (Mnemonic == "teq" || Mnemonic == "vceq" ||
18178ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "movs" ||
18188ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "svc" ||
18198ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "mls" || Mnemonic == "smmls" || Mnemonic == "vcls" ||
18208ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vmls" || Mnemonic == "vnmls") ||
18218ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacge" || Mnemonic == "vcge" ||
18228ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vclt" ||
18238ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vacgt" || Mnemonic == "vcgt" ||
18248ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      Mnemonic == "vcle" ||
18258ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar      (Mnemonic == "smlal" || Mnemonic == "umaal" || Mnemonic == "umlal" ||
18268ab1112bdc30b8675bb12431d8b5b270da42f1b5Daniel Dunbar       Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" ||
1827d1f0bbee189ea7cd18d03c4f9f55d0a33b070814Jim Grosbach       Mnemonic == "vqdmlal" || Mnemonic == "bics"))
1828352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
1829badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1830352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // First, split out any predication code.
1831badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
1832345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("eq", ARMCC::EQ)
1833345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ne", ARMCC::NE)
1834345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hs", ARMCC::HS)
1835660a9ec4aa08b42a1379e5caa3935d301b1e27b7Jim Grosbach    .Case("cs", ARMCC::HS)
1836345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lo", ARMCC::LO)
1837660a9ec4aa08b42a1379e5caa3935d301b1e27b7Jim Grosbach    .Case("cc", ARMCC::LO)
1838345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("mi", ARMCC::MI)
1839345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("pl", ARMCC::PL)
1840345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vs", ARMCC::VS)
1841345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("vc", ARMCC::VC)
1842345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("hi", ARMCC::HI)
1843345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ls", ARMCC::LS)
1844345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("ge", ARMCC::GE)
1845345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("lt", ARMCC::LT)
1846345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("gt", ARMCC::GT)
1847345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("le", ARMCC::LE)
1848345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Case("al", ARMCC::AL)
1849345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    .Default(~0U);
1850badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  if (CC != ~0U) {
1851badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
1852352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    PredicationCode = CC;
185352925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
1854345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1855352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
1856352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
1857352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
1858352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
1859352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "movs" || Mnemonic == "mrs" || Mnemonic == "smmls" ||
1860352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vabs" || Mnemonic == "vcls" || Mnemonic == "vmls" ||
1861352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vmrs" || Mnemonic == "vnmls" || Mnemonic == "vqabs" ||
1862352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar        Mnemonic == "vrecps" || Mnemonic == "vrsqrts")) {
1863352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
1864352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
1865352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
1866352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
1867a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
1868a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
1869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
1870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
1871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
1872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
1873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
1874a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
1875a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
1876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
1877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
1878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
1879a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
1880a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1882352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
1883352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
18843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
18853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
18863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
18873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
18883771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
1889fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
1890fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso LopesGetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
1891fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
1892eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
1893eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
1894eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
1895eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
1896be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
1897eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
1898eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
1899be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "eor" || Mnemonic == "smlal" ||
1900ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
1901eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
1902eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
1903eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
1904eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
19053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
1906eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
1907eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
1908eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
1909eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
1910e47f3751d7770916f250a00a84316d412e959c00Bruno Cardoso Lopes      Mnemonic == "dsb" || Mnemonic == "movs" || Mnemonic == "isb" ||
1911a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic == "clrex" || Mnemonic.startswith("cps")) {
19123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
19133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
19143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
19153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
1916fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
1917ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
1918fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
191963b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
1920fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
1921badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
1922badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1923badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
1924badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
1925badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1926badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
1927badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
1928badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  StringRef Head = Name.slice(Start, Next);
1929badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
1930352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
1931352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
1932a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
1933352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
1934a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Head = SplitMnemonic(Head, PredicationCode, CarrySetting,
1935a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                       ProcessorIMod);
1936badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
19373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
19389717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
19393771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
19403771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
19413771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
19423771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
19433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
19443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
19453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
19463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
19473771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode);
19483771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
19493771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
19503771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
19513771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
19523771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
19533771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
19543771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptCarrySet) {
19553771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
19563771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
19573771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
19583771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a carry set, but the user wrote one (or
19593771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // misspelled another mnemonic).
19603771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
19613771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
19623771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
19633771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
19643771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
19653771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
19663771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
19673771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
19683771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
19693771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // This mnemonic can't ever accept a predication code, but the user wrote
19703771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // one (or misspelled another mnemonic).
19713771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
19723771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    // FIXME: Issue a nice error.
1973badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
1974345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1975a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
1976a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
1977a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
1978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
1979a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
1980a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
1981a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
1982a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
1983a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1984a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
1985a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1986a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1987345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
19885747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
19895747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
19905747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
1991a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
1992a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1993a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
19945747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
19955747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
19965747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
19975747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1998a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
1999fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (ParseOperand(Operands, Head)) {
2000cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
2001cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
2002cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
2003a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2004a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
2005b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
2006a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2007a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
2008fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      if (ParseOperand(Operands, Head)) {
2009cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
2010cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
2011cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
2012a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
2013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
201416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2015cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2016cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
201734e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
2018cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
2019146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
202034e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
20219898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
2022ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2023ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2024fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
2025fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
2026fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2027fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
2028fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
2029fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
2030193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResultTy MatchResult, MatchResult2;
2031193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2032193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  if (MatchResult != Match_Success) {
2033193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_InvalidOperand it might be some arithmetic instruction
2034193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that does not update the condition codes.  So try adding a CCOut operand
2035193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // with a value of reg0.
2036193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    if (MatchResult == Match_InvalidOperand) {
2037193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      Operands.insert(Operands.begin() + 1,
2038193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                      ARMOperand::CreateCCOut(0,
2039193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                                  ((ARMOperand*)Operands[0])->getStartLoc()));
2040193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2041193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (MatchResult2 == Match_Success)
2042193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult = Match_Success;
204344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      else {
204444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
2045193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.erase(Operands.begin() + 1);
204644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete CCOut;
204744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby      }
2048193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2049193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // If we get a Match_MnemonicFail it might be some arithmetic instruction
2050193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // that updates the condition codes if it ends in 's'.  So see if the
2051193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // mnemonic ends in 's' and if so try removing the 's' and adding a CCOut
2052193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    // operand with a value of CPSR.
2053eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng    else if (MatchResult == Match_MnemonicFail) {
2054193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      // Get the instruction mnemonic, which is the first token.
2055193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      StringRef Mnemonic = ((ARMOperand*)Operands[0])->getToken();
2056193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      if (Mnemonic.substr(Mnemonic.size()-1) == "s") {
2057193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        // removed the 's' from the mnemonic for matching.
2058193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        StringRef MnemonicNoS = Mnemonic.slice(0, Mnemonic.size() - 1);
2059193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        SMLoc NameLoc = ((ARMOperand*)Operands[0])->getStartLoc();
206044a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
206144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.erase(Operands.begin());
206244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        delete OldMnemonic;
206344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby        Operands.insert(Operands.begin(),
2064193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateToken(MnemonicNoS, NameLoc));
2065193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        Operands.insert(Operands.begin() + 1,
2066193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                        ARMOperand::CreateCCOut(ARM::CPSR, NameLoc));
2067193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        MatchResult2 = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2068193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        if (MatchResult2 == Match_Success)
2069193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby          MatchResult = Match_Success;
2070193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        else {
207144a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *OldMnemonic = ((ARMOperand*)Operands[0]);
207244a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin());
207344a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete OldMnemonic;
207444a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.insert(Operands.begin(),
2075193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby                          ARMOperand::CreateToken(Mnemonic, NameLoc));
207644a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          ARMOperand *CCOut = ((ARMOperand*)Operands[1]);
207744a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          Operands.erase(Operands.begin() + 1);
207844a9e8f869dd9d04a04eb556ff0ff4a1039d371fKevin Enderby          delete CCOut;
2079193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby        }
2080193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby      }
2081193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby    }
2082193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  }
2083193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2084e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2085fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2086fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2087e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2088e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2089e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2090e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2091e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2092e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2093e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2094e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
209516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2096e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2097e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2098e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
209916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2100e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2101e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2102e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2103e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2104b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2105b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2106fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
210716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2108c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2109146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2110fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2111fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
2112515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirective parses the arm specific directives
2113ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2114ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2115ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
2116ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    return ParseDirectiveWord(4, DirectiveID.getLoc());
2117515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
2118515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumb(DirectiveID.getLoc());
2119515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
2120515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveThumbFunc(DirectiveID.getLoc());
2121515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
2122515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveCode(DirectiveID.getLoc());
2123515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
2124515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return ParseDirectiveSyntax(DirectiveID.getLoc());
2125ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2126ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2127ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2128ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby/// ParseDirectiveWord
2129ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
2130ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2131ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2132ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2133ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2134ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2135ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2136ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2137aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2138ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2139ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2140ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
214116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2142ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2143ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2144ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2145b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2146ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2147ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2148ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2149b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2150ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2151ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2152ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2153515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumb
2154515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
2155515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
2156515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2157515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2158b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2159515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2160515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2161515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2162515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2163515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2164515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2165515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2166515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveThumbFunc
2167515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
2168515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
21696469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
21706469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
21716469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
21726469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
21736469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
21746469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
21756469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
21766469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
21776469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
21786469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
21796469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
21806469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
21816469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
21826469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2183515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2184515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2185b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2186515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
21876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
21886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
21896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
21906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
21916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2192642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2193642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2194642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2195515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2196515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2197515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2198515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveSyntax
2199515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
2200515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
220118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2202515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2203515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
220438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
220558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2206b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
220758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
22089e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2209515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2210515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2211515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2212515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
221318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2214b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2215515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2216515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2217515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2218515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2219515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2220515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2221515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby/// ParseDirectiveCode
2222515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
2223515d509360d81946247fd0f937034cdf1f237c72Kevin Enderbybool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
222418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2225515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2226515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
222718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
222858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2229b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
223058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2231b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2232515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2233515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2234515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2235515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
223618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2237b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2238515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
223932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
224032869205052430f45d598fba25ab878d8b29da2dEvan Cheng    if (!isThumb()) SwitchMode();
22412a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
224232869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
224332869205052430f45d598fba25ab878d8b29da2dEvan Cheng    if (isThumb()) SwitchMode();
22442a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2245eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
22462a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2247515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2248515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2249515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
225090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
225190b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
22529c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2253ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
2254ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> X(TheARMTarget);
2255ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  RegisterAsmParser<ARMAsmParser> Y(TheThumbTarget);
225690b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2257ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
22583483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
22590692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
22600692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
22613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2262