ARMAsmParser.cpp revision 039c2e19c4237fb484315a62e95222ac28640bb7
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
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "MCTargetDesc/ARMBaseInfo.h"
11ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMAddressingModes.h"
12ee04a6d3a40c3017124e3fd89a0db473a2824498Evan Cheng#include "MCTargetDesc/ARMMCExpr.h"
13c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmLexer.h"
14c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCAsmParser.h"
15c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
166469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola#include "llvm/MC/MCAsmInfo.h"
17642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach#include "llvm/MC/MCContext.h"
18ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCStreamer.h"
19ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCExpr.h"
20ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/MC/MCInst.h"
2194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
22ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2394b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
24ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby#include "llvm/Target/TargetRegistry.h"
25c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
26fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2775ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
2894b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
29c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
300c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
31345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
33ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
34ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
35ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
363a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
37146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
38146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
3916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4094b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
41ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
42ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
43ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
44ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
48ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
49ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
520d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
531355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
551355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
561355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
571355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  const MCExpr *applyPrefixToExpr(const MCExpr *E,
589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
60a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
631355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
641355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
661355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
68515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
705f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod);
711355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
72fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
7316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
74ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
75ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
76ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
77ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
78ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
79ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
80ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
8132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
82ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
83ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
8432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
85ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
86a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
87a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
890692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
900692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
91a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
92a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
9443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
95f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
9643904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
97f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
9843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
998bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
10043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1018bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
10243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1038bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
104f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
105f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
106f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
107f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
108f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
109f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
110f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
111f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
112c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
113580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
115293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
117ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
118ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
1191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
120ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1211355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
122ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
131189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
132189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
133189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
134189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
135ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
136ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
13794b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
13932869205052430f45d598fba25ab878d8b29da2dEvan Cheng
140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
141ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
142ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
143ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
1441355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
1451355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
1461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
147189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
1481355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
1491355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
1501355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
1511355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
153ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
15416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
15516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1563a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
1573a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
158a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
159a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
160146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
161762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
1628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
163d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
164fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
165fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
166cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
167706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
1688462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
1697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    PostIndexRegister,
170584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
171a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
1728462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
1738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
1740f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
1750f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
176e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
17792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ShiftedImmediate,
178580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ShifterImmediate,
1797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    RotateImmediate,
180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    BitfieldDescriptor,
1818462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
184762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
18524d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
186a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
187a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
1898462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
1908462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
1918462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
1928462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
193706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      ARM_MB::MemBOpt Val;
194706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    } MBOpt;
195706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
196706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    struct {
197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
200fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
201a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
202a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
203a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
204a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
205584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
206584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
207584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
208584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
209a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
210a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
211a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
212a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
213a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
214a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
215a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2178155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
218cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
219cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
22016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2216a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
222a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
223a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
2247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
2257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
2267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
2277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
2287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
2297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned ShiftValue;      // shift for OffsetReg.
2307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
2320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
2330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
2347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
2357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned Imm;
2367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
2377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
239580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
241580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
247af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
24892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
24992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
25092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
25192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
252af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
2537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
2547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
2557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
256293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
257293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
258293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
259293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
26116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
262146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
263146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
264762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
265762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
266762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
267762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
268762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
2698462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
2708462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
2718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
272762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
2738462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
274762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
275d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
276762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
277762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
278762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2798d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
2800f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
2810f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
28224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
2838d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
284fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
285fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
286fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
287fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
288762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
289762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
290762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
291706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
292706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
293706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
294762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
295762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
296762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
2977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    case PostIndexRegister:
2987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
2997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
300584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
301584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
302584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
303a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
304a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
3050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
306580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    case ShifterImmediate:
307580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
3080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
309e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
310af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
311e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
31292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    case ShiftedImmediate:
313af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
31492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
3157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    case RotateImmediate:
3167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
3177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
318293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    case BitfieldDescriptor:
319293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
320293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
321762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
322762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
32316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
324762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
325762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
326762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
327762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
328a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3298462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
3308462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
3318462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
3328462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
3338462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
334fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
335fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
336fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
337fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
338fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
339a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
340a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
341a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
342a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
343a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
344a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
3456aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
3467729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
347a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
348a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3495fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
3500f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
3510f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
35224d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
3538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
3548d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
355cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
356cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
357cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
358cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
359cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
360706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
361706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
362706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
363706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
364706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
365a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
366a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
367a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
368a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
369a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
370584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
371584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
374584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
375fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
376fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
3778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
378d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
3793483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
3806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
3816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
3826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
3836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
3846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
3856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
3866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
3876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
38883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
38983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
39083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
39183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
39283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
39383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
39483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
39583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
39683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
39783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
39883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
39983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
40083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
40183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
40283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
40383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
4047c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
4057c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (Kind != Immediate)
4067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
4077c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
4097c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
4107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
4117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
412f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
413f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (Kind != Immediate)
414f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
415f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
416f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
417f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
418f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
419f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
4204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
4214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (Kind != Immediate)
4224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
4234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4244a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
4254a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
4264a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
4274a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
428fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
429fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
430fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
431fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
432fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
433fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
434fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
435fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
436ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
437ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (Kind != Immediate)
438ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
439ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
440ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
441ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
442ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
443ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
444ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
445ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
446ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
447ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (Kind != Immediate)
448ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
449ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
450ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
451ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
452ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
453ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
454f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
455f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
456f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
457f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
458f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
459f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
460f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
461f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
462f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
463f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
464f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
465f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
466f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
467f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
468f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
469f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
4706bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
4716bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (Kind != Immediate)
4726bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
4736bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4746bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
4756bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
4766bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
4776bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
4786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
4796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
4856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
486c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
487c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (Kind != Immediate)
488c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
489c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
490c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
491c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
492c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
493c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
494b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
4958d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
4960f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
4970f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
49814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
499706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
50014b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
5017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxReg() const { return Kind == PostIndexRegister; }
502580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isShifterImm() const { return Kind == ShifterImmediate; }
503af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
504af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
5057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  bool isRotImm() const { return Kind == RotateImmediate; }
506293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  bool isBitfield() const { return Kind == BitfieldDescriptor; }
5077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemNoOffset() const {
5087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
509ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
5107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
5117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0;
512ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
5137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
5147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
515ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
5167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
5177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return true;
5187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
5197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
5207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
5217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
5227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
523039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
524039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Kind != Immediate)
525039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
526039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
527039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
528039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
529039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
530039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
531039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
5327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
5337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
534ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
5357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
5367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return false;
5377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
5387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
5397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
5407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val >= -1020 && Val <= 1020 && ((Val & 3) == 0);
5417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
5427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
5437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum)
544ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
545ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
546ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
5477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
5487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
5497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
5507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
5517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
55287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
553505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes    return true;
554505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
5557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
5567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
557f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
5587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
5597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
5607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
5617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -256 && Val < 256;
562f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
5637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
5647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
565ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
5667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
5677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
5687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
5697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
5707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
5717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
5727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Immediate)
5737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
5747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
575ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
5767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
5777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -256 && Val < 256;
578ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
5797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
580584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
581a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
5823483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
58414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
58514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
58614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
58714b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
5883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
5893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
5903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
5913483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
5923483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
5938462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
594345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
5958462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
59604f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
59704f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
5988462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
5998462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
600fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
601fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
602fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
603fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
604fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
605fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
606fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
607fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
608fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
609fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
610d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
611d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
612d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
613d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
614d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
615a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
616a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
617a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
618a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
619a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
620af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
621e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
622af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
623af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
624af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
625e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
626af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
627e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
628e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
629af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
630152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
631af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
632af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
63392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
634af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
63592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
63692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
63792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
638580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
6390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
640580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
641580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
6420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
6430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
64487f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
6457729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
6465fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
6475fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
6487729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
6497729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
65087f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
65187f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
6520f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
6530f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
6540f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
6550f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
6560f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
6570f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
6580f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
6590f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
6607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
6617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
6637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
6647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
6657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
666293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
667293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
668293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
669293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
670293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
671293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
672293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
673293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
674293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
675293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
676293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
6773483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
6786b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6796b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
6826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
6836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
6856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
6866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
68783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
68883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
68983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
69083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
69183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
69283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
6937c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
6947c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
6957c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
6967c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
6977c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
69883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
69983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
70083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
70183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
702f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
703f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
704f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
705f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
706f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
707f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
708f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
709f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
7104a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
7114a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
7124a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
7134a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
7144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
7154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
7164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
7174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
718fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
719fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
720fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
721fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
722fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
723ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
724ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
725ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
726ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
727ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach
728ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
729ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
730ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    addExpr(Inst, getImm());
731ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
732ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
733f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
734f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
735f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
736f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
737f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
738f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
739f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
740f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
741f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
742f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
743f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
744f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
745f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
746f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
7476bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
7486bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
7496bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
7506bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
7516bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
7526b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
7533483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
7543483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
7553483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
75616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
757c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
758c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
759c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
760c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
761c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
762706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
763706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
764706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
765706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
766706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
7677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
7687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
7697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
770505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
771505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
7727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
7737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
7747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
7757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetRegNum) {
7767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
7777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
7787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
7797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
7807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
7817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
7827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
7837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
7847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
7857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              0, Mem.ShiftType);
786ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
7877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
7887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
7897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
790ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
791ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
792039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
793039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
794039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
795039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
796039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
797039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
798039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
799039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
800039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
801039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
802039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
803039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
804039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
805039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
8067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
8077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
8087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
8097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
8107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
8117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
8127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
8137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
8147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
8157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
8167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
8177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
8187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
8197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
8207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
8217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
8227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
8237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
824ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
825ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
8267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
8277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
8287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
8297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
8307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
8317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
83292b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
8337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
8347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
8357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
8367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                     Mem.ShiftValue, Mem.ShiftType);
8377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
8387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
8397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
8407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
841d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
8427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
8437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
8447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
8457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
84614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
8473483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
8487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
8497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
8517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
8527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
8537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
8547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
8557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
856f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
857ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
8587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
8597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
8607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
8617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.Imm));
862ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
863ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
864584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
865584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
866584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
867584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
868584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
874b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
875b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
8763a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
8773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
878345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
879345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
880345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
8813a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
882345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
883345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
884fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
885fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
886fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
887fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
888fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
889fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
890fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
891fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
892fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
893fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
894fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
895fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
896fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
897fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
898fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
899fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
900d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
901d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
902d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
903d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
904d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
905d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
906d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
907d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
9083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
9093a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
910762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
911762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
912762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
913762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
9143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
915a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
916a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
91750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
9183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
919762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
920762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
921762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
9223a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
923a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
924a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
925e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
926e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
927e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
928e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
929e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
930e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
931af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
932af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
933af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
934af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
935e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
936e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
937e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
938e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
939e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
94092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
94192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
94292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
94392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
94492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
945af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
946af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
947af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
94892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
94992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
95092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
95192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
95292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
953580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
9540082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
955580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ARMOperand *Op = new ARMOperand(ShifterImmediate);
956580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
957580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
9580082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
9590082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
9600082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
9610082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
9620082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
9637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
9647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    ARMOperand *Op = new ARMOperand(RotateImmediate);
9657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
9667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
9677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
9687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
9697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
9707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
971293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
972293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
973293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    ARMOperand *Op = new ARMOperand(BitfieldDescriptor);
974293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
975293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
976293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
977293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
978293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
979293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
980293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
9817729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
9825fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
983cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
9840f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
9850f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
986275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng    if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].
987275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng        contains(Regs.front().first))
9880f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
989275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng    else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].
990275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
9910f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
9920f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
9930f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
9945fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
9957729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
99624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
997cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
998cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
999cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
10008d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
10018d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
10028d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
10033a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
10043a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
1005762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1006762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1007762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
10083a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1009cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1010cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
10117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
10127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
10137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
10147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
10157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned ShiftValue,
10167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
10173a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
10183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
1019762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
10207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetImm = OffsetImm;
10217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetRegNum = OffsetRegNum;
1022762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
10237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.ShiftValue = ShiftValue;
10247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.isNegative = isNegative;
10257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
10267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
10277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
10287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
102916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
10307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, unsigned Imm,
10317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
10327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARMOperand *Op = new ARMOperand(PostIndexRegister);
10337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
10347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.Imm = Imm;
1035762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1036762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
10373a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1038a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1039706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1040706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
1041706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
1042706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1043706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1044706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1045706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1046706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1047a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1048a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1049a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
1050a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1051a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1052a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1053a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1054a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1055584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1056584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1057584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
1058584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1059584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1060584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1061584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1062584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1063a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1064a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1065a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1066a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1067b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1068fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
1069fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
10706a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1071fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1072d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
1073d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1074d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
1075fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
1076fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1077fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1078fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
1079fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1080fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1081584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
1082584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1083584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
1084fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
1085fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1086fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1087706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
1088706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1089706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
1090fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
10916ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
10927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << " base:" << Mem.BaseRegNum;
10936ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1094fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
10957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  case PostIndexRegister:
10967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    OS << "post-idx register "
10977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << getAddrOpcStr(ARM_AM::getAM3Op(PostIdxReg.Imm))
10987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << PostIdxReg.RegNum
10997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << ">";
11007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
1101a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
1102a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1103a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1104a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1105a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1106a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1107a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1108a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1109a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1110fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
111150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1112fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1113580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  case ShifterImmediate:
1114580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1115580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
1116e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
1117e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
111892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1119af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedReg.SrcReg
1120af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1121af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << RegShiftedReg.ShiftReg << ", "
1122af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1123e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
11240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
112592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  case ShiftedImmediate:
112692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
1127af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedImm.SrcReg
1128af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1129af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
113092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
113192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
11327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  case RotateImmediate:
11337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
11347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
1135293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  case BitfieldDescriptor:
1136293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1137293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
1138293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
11390f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
11400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
11410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
11428d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
11438d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
11445fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
11455fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
11467729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
11477729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
11487729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
11498d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
11508d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
11518d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
11528d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
11538d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1154fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1155fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1156fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1157fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1158fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
11593483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
11613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
11623483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
11643483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
11653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
11663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
116769df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
116869df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
11691355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
1170bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1171bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1172bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1173bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
11749c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1175e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1176e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
11773a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
11781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
117918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
11807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
1181d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1182a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1183a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
11840c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
11850c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
11860c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
11870c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
11880c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
11890c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
11900c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
11910c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
11920c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
11930c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
11940c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
11950c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
119669df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1197b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1198e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1199e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1200d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
120119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
120219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
120319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
120419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
120519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
12060d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
12070082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
12080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
12090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
12100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
12110082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
12130082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
12140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
12150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
12160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
12170082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
12180082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
12190082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
12200082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
12210082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12220082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
122319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
12240082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1225e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1226e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1227e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1228e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1229e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1230eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1231e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1232e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1233e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1234e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1237e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1238e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1241e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1242e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1243e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1244e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
124719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
124819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
124919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
125019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1251e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1252e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
125319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
125419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
125519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
125619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1257e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1258e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1259e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1260e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1261e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1262e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1263e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
126419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
126519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1266e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1267e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
12681355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
1269e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
127019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
127119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
127219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
127319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
127419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
127519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1276e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
127719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
127819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1279e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1280e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
128192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
128292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1283af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
12840082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
128592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
128692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
128792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
12880082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
128919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
12900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
12910082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12920082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
129350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
129450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
129550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1296e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1297e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1298e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
129950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
13001355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1301e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
13021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
1303e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
130450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1305d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
130650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1307a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1308e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1309e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
131050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
131150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1312e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
131399e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
131499e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
131550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1316a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1317a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1318fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1319fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1320fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1321fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1322e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1323e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1324e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1325e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1326e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1327fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1328e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1329e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1330e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1331e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1332e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1333e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1334e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1335e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1336e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1337e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1338e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1339e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1340e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1341e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1342e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1343e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1344fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1345e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1346e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1347e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1348e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1349e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1350e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1351e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1352e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1353e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1354e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1355e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1356e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1357e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1358e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1359e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1360e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
136143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
1362fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1363fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1364f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
136543904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1366e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1367e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1368e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1369e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1370fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1371e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1372f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1373e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1374e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1375fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1376f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1377fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1378fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
137943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
1380fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1381fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1382f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
138343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1384fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1385fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1386fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1387fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1388fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1389fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1390f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1391fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1392fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1393fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1394f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1395e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1396e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1397c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1398c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
139950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
14001355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
140118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1402a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1403e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
140416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
14057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
14067729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
14075fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1408d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
14097729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1410e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
14117729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1412d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
141318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1414d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1415c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1416c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
141750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1418c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1419e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14201355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    int RegNum = tryParseRegister();
1421c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1422c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
142350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1424c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1425d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1426e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1427e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1428e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1429e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1430e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1431e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1432e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1433e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1434e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1435e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1436e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
14377729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
14387729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1439e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1440e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
144118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1442c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1443c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
144450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1445c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1446d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1447e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1448e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
144903f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1450e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
14515fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
1452e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    RI = Registers.begin(), RE = Registers.end();
1453e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14547caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  unsigned HighRegNum = getARMRegisterNumbering(RI->first);
14558e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
14568e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling
14577caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  DenseMap<unsigned, bool> RegMap;
14587caebff83d90a59aa74876ff887e822387f479e0Bill Wendling  RegMap[HighRegNum] = true;
14597caebff83d90a59aa74876ff887e822387f479e0Bill Wendling
1460e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  for (++RI; RI != RE; ++RI) {
14617729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    const std::pair<unsigned, SMLoc> &RegInfo = *RI;
14627caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1463e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14648e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1465e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
146650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1467e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1468e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14698e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1470e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1471e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1472e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
14738e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    RegMap[Reg] = true;
14748e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1475e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1476e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
147750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
147850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1479d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1480d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
148143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1482f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
148343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1484706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1485706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1486706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1487706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1488706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1489706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1490706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1491706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1492032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
1493706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1494032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
1495706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1496706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1497032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
1498706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1499032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
1500706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1501706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1502706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1503706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1504706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1505f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1506706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1507706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1508706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1509f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1510706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1511706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
151243904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1513a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
151443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1525a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1526a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1527a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1528a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1530a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1532a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1533a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1534a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1535a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1536a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1537a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1538a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1539584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1540584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
154143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1542584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
154343904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1544584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1545584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1546584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1547584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1548584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1549584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1550584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1551584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1552b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
1553584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1554584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1555584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1556584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1557584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1558584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1559584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1560584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1561584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1562584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1563b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
1564584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1565584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1566584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1567584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
15684b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1569584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1570584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1571584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1572584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
15734b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1574584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
157556926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
157656926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1577584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1578584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1579584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1580584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1581584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1582584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1583584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1584584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1585584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1586584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1587584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1588584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1589584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1590584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1591584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1592584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1593584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1594584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1595584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1596584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1597584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1598584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1599584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1600584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1601584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1602584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1603584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1604584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1605a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1606a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1607f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1608f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
1609f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
1610f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1611f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1612f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1613f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1614f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1615f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
1616f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
1617f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
1618f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
1619f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1620f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1621f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1622f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
1623f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1624f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
1625f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1626f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1627f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1628f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1629f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
1630f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1631f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
1632f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
1633f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1634f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
1635f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1636f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1637f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1638f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
1639f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
1640f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1641f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1642f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
1643f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
1644f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
1645f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1646f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1647f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1648f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
1649f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1650f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
1651f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
1652f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1653c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1654c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1655c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1656c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
1657c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1658c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
1659c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
1660c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1661c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
1662c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
1663c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
1664c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
1665c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
1666c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1667c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
1668c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
1669c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
1670c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
1671c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
1672c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
1673c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
1674c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
1675c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
1676c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
1677580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
1678580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
1679580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
1680580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
1681580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
1682580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1683580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1684580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
1685580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
1686580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1687580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
1688580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1689580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1690580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
1691580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
1692580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
1693580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
1694580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
1695580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
1696580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
1697580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
1698580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1699580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1700580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
1701580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1702580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
1703580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1704580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1705580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1706580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1707580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
1708580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1709580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
1710580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
1711580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1712580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
1713580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1714580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1715580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1716580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
1717580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
1718580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
1719580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1720580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1721580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
1722580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
1723580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
1724580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
1725580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
1726580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
1727580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
1728580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // asr #32 encoded as asr #0.
1729580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
1730580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
1731580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
1732580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
1733580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
1734580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
1735580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
1736580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
1737580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1738580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
1739580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
1740580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
1741580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
1742580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
1743580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
17447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
17457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
17467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
17477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
17487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
17497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
17507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
17517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
17527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(S, "rotate operator 'ror' expected");
17537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
17547e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
17567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR") {
17577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(S, "rotate operator 'ror' expected");
17587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
17597e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17607e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
17617e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
17627e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
17637e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
17647e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
17657e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
17667e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17677e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
17687e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
17697e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
17707e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
17717e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
17727e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
17737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
17747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
17767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
17777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
17787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
17797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
17817e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
17827e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
17837e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
17847e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
17857e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
17867e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
17877e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
17887e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
17897e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
17907e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
17917e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
17927e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
17937e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
17947e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
17957e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1796293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1797293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1798293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
1799293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
1800293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1801293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1802293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1803293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1804293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
1805293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1806293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
1807293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
1808293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
1809293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
1810293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1811293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1812293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
1813293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
1814293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
1815293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1816293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1817293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1818293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
1819293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
1820293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
1821293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
1822293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1823293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1824293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
1825293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1826293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
1827293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
1828293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
1829293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1830293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1831293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
1832293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1833293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1834293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1835293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1836293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
1837293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1838293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
1839293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
1840293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
1841293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1842293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1843293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
1844293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
1845293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
1846293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1847293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1848293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1849293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
1850293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
1851293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
1852293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
1853293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
1854293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1855293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
1856293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1857293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
1858293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
1859293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
1860293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
1861293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
18627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
18637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
18647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
18657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // postidx_reg := '+' register
18667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  //              | '-' register
18677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  //              | register
18687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
18697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
18707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
18717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
18727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
18737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
18747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
18757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  unsigned Imm = ARM_AM::getAM3Opc(ARM_AM::add, 0);
18767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
18777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
18787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
18797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
18807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
18817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
18827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = ARM_AM::getAM3Opc(ARM_AM::sub, 0);
18837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
18847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
18857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
18867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
18877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
18887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
18897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
18907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
18917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
18927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
18937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
18947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
18957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, Imm, S, E));
18967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
18977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
18987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
18997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
19001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1901ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1902ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1903ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
19041355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1905ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1906ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1907ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1908ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1909ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
1910ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
19117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
1912ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1913ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1914ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1915ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
19161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
1917ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1918ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1919ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
19201355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
1921ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1922ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1923ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
19247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(0 && "cvtStWriteBackRegAddrMode2 not implemented yet!");
19257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
19267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
19277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
19287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
19297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
19307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
19317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
19327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
19337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
19347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
1935ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
19367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
19377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
19387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
19397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
19407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
19417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
19427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
1943ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1944ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
1945ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
1946ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
19477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
1948ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1949ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1950ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
19517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
19527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
19537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
1954aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
1955ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1956ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
19577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
19587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
19597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
19607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
19617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
19627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
19637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
19647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
1965aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
19667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
19677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
19687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
19697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
19707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
19717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
19727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
19737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
19747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
19757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
19767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
19777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
19787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
19797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
19807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
1981ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
1982ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
1983ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
1984ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
19857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
1986ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
1987ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
1988ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
19897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
19907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1991ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
1992ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
19937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
1994ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
19957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
19967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
19977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
19987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
19997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2000ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2001ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2002ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2003ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
2004e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
20059c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
200650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
20077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2008762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
200918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
2010a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
2011762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
2012b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
2013a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
201418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
20151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
20167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
20177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
2018a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
20190571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
20200571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
20210571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
20227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
20230571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
20247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
2025762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
2026b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
2027a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
20287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
20297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             0, false, S, E));
203003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
20317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
20327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
203350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
20347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
20357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
203650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
20377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If we have a '#' it's an immediate offset, else assume it's a register
20387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset.
20397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
20407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '#'.
20417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
204250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
20437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // FIXME: Special case #-0 so we can correctly set the U bit.
2044e2a98dd2a4f007d5d9d3c71460cfbe0a825b8993Kevin Enderby
20457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
20467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
20477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
204805d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
20497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
20507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
20517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
20527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
20537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
20547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
20557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
20567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
20577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
20587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
20597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
20607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
206105d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
20627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
20637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
20647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
20657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             ARM_AM::no_shift, 0, false, S,E));
2066a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
20677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
20687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
20697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
20707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
20717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
2072762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
20737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
20747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
20759c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
2076d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
20777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
20787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
20797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
20807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
20817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
20827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
20837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
20847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
20857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
20869c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
20877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
20887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
20897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
20907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
20917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
20927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
20937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
20947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  unsigned ShiftValue = 0;
20957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
20967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
20977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftValue))
20987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
20999c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
210016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
21017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
21027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
21037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
21047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
21057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
21067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
21077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
21087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           ShiftType, ShiftValue, isNegative,
21097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
21107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
21117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
21129c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
21139c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
21149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
21159c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
21167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
2117a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
2118a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
21197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
21207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
21217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
21227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
212318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2124a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2125a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
212638e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
2127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
21280082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
2129a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
21300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
2131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
21320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
2133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
21340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
2135a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
21360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
2137a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
21387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
2139b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
2140a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
21417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
21427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
21437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
21447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
21457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
21467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
21477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (HashTok.isNot(AsmToken::Hash))
21487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
21497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
21509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
21517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
21527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
21537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
21547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
21557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
21567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
21577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
21587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
21597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
21607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
21617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
21627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
21637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
21647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
21657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
21667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
2167a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2168a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
2169a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2170a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
21719c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
21729c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
21731355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2174fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
2175762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
2176fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2177fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
2178fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
2179f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2180f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
2181fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
2182f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
2183f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
2184f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
2185f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
2186f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
2187fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2188a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
2189146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
2190146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
219150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
219219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
21931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
219450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
21950d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
219619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
21970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
219819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
219919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
2200e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2201e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
2202e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
220319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
220467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
220567b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
2206515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
2207515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
2208515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
2209762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2210515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
221150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2212762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
221350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
221450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
221550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
2216a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
22171355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
2218d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
22191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
2220d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::Hash:
2221079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
2222079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
2223762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2224b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2225515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
2226515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
222750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2228762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
222950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
223050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
22319081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
22329081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
22337597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
22347597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
22357597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
22361355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
22379081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
22389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22397597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
22407597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
22419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
22429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22437597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
22447597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
22459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
22467597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
22479081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
22489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
2249a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
22521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
22537597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
22541355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
22557597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
22569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
22588a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
22599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
22609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
22629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
22639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
22649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
22659081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
22679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
22687597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
22699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
22707597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
22719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
22729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
22739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
22749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
22759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
22769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
22789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
22799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
22809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
22819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
22829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
22839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
22849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
22861355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E,
22879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
22889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
22899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
22909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
22919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
22929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
22949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
22959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
22969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
22979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
22989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
22999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
23009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
23019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
23029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
23039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
23049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
23059081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
23069081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
23079081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
23089081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
23099081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
23109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
23119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
23129081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
23131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant);
23149081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
23159081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
23169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
23179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
23189081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
23199081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
23209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
23219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
23229081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
23239081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
23249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
23259081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
2326352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
2327352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
2328352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
2329badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
23301355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
23315f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
23325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
23335f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &ProcessorIMod) {
2334352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
2335352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
2336a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
2337352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2338badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
2339352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
2340352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
23415f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
23425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
23435f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
23445f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
23455f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
23465f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
23475f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
23485f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
2349352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
2350badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
23513f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
23523f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
2353ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
235471725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
235549f2ceddd25c75373f8a39fa25e8b9db33bcdaccJim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls") {
23563f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
23573f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
23583f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
23593f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
23603f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
23613f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
23623f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
23633f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
23643f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
23653f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
23663f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
23673f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
23683f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
23693f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
23703f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
23713f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
23723f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
23733f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
23743f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
23753f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
23763f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
23773f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
23783f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
237952925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
2380345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2381352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
2382352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
2383352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
2384352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar      !(Mnemonic == "asrs" || Mnemonic == "cps" || Mnemonic == "mls" ||
23855f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
23865f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
23875f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
2388e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
2389e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
2390352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
2391352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
2392352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
2393352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2394a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
2395a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
2396a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
2397a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
2398a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
2399a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2400a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
2401a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
2402a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
2403a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
2404a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2405a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
2406a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
2407a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2408a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2409352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
2410352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
24113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
24123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
24133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
24143771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
24153771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
2416fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
24171355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
2418fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
2419eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
2420eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
2421eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
2422eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
2423be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
2424eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
2425eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
2426be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "eor" || Mnemonic == "smlal" ||
2427ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng      (Mnemonic == "mov" && !isThumbOne())) {
2428eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
2429eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
2430eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
2431eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
24323771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
2433eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
2434eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
2435eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
2436eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
24375f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
2438c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      Mnemonic == "setend" ||
243948c693ff564c422153733424ab845106161430acJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) ||
2440e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs"))
2441e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        && !isThumb()) ||
24425f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
24433771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
24443771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
24453771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
24463771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
2447fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
2448ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
2449fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
245063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
2451fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
2452badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
2453badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2454badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
2455badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
2456badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2457badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
2458badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
2459ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
2460badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2461352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
2462352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
2463a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
2464352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
24651355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
2466c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                           ProcessorIMod);
2467badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
2468ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
2469ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2470ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
2471ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
24729717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
24733771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
24743771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
24753771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
24763771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
24773771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
24783771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
24793771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
24803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
24811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
24823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
248333c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
248433c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
248533c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
248633c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
2487ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
248833c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
248933c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
2490c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
2491c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
2492c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
2493c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
2494c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
2495c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
2496c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
249733c16a27370939de39679245c3dff72383c210bdJim Grosbach
24983771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
24993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
25003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // FIXME: It would be awesome if we could somehow invent a location such that
25013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // match errors on this operand would print a nice diagnostic about how the
25023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // 's' character in the mnemonic resulted in a CCOut operand.
250333c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (CanAcceptCarrySet)
25043771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
25053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                                               NameLoc));
25063771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
25073771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
25083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
25093771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
25103771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar                         ARMCC::CondCodes(PredicationCode), NameLoc));
2511badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
2512345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2513a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
2514a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
2515a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
2516a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
2517a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
2518a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  } else {
2519a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // This mnemonic can't ever accept a imod, but the user wrote
2520a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // one (or misspelled another mnemonic).
2521a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2522a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // FIXME: Issue a nice error.
2523a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2524a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
2525345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
25265747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
25275747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
25285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
2529a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
2530a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2531a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
25325747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
25335747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
25345747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
25355747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2536a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
25371355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
2538cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
2539cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
2540cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
2541a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2542a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
2543b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
2544a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2545a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
25461355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
2547cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
2548cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
2549cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
2550a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
2551a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
255216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2553cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2554cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
255534e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
2556cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
2557146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
255834e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
2559ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2560ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2561ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
2562ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
2563ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
2564ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // operand if that's the instruction we're trying to match.
2565ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  //
2566ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // We do this post-processing of the explicit operands rather than just
2567ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // conditionally adding the cc_out in the first place because we need
2568ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // to check the type of the parsed immediate operand.
2569ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  if (Mnemonic == "mov" && Operands.size() > 4 &&
2570ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
2571731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
2572731f2097944bfdf5b58ff1f19560a25ed15c9b2bJim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0) {
2573ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
2574ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
2575ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
2576ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
2577ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
2578cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
2579cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
2580cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
2581cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // a CondCode operand in the list. If we're trying to match the label
2582cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // version, remove the CondCode operand here.
2583cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
2584cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
2585cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
2586cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
2587cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
2588cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
25899898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
2590ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2591ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2592189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
2593189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
2594189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
2595189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
2596189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2597189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
2598189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
2599189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
2600189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
2601189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
2602189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
2603189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
2604189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
2605189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
2606189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
2607189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
2608189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
2609189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
2610189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
2611189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
2612189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[4]->getStartLoc(),
2613189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
2614189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
2615189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
2616fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
2617fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
2618fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
2619fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
2620fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
2621fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
2622fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
2623fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
2624fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
2625189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
2626189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
2627189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
2628189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
2629189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
2630fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
2631fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
2632fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2633fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
2634fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
2635fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
26365a18700470f0831b9b2af78862672561dd980345Jim Grosbach  MatchResultTy MatchResult;
2637193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
2638193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
2639e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
2640189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
2641189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
2642189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (validateInstruction(Inst, Operands))
2643189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
2644189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
2645fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
2646fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
2647e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
2648e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2649e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
2650e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
2651e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
2652e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
2653e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
2654e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
265516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2656e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
2657e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
2658e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
265916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2660e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
2661e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
2662e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
2663e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(IDLoc, "unrecognized instruction mnemonic");
2664b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
2665b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar    return Error(IDLoc, "unable to convert operands to instruction");
2666fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
266716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2668c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
2669146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
2670fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
2671fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
26721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
2673ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
2674ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
2675ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
26761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
2677515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
26781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
2679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
26801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
2681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
26821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
2683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
26841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
2685ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
2686ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2687ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
26881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
2689ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
26901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2691ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2692ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
2693ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
2694ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
2695ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
2696ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2697aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
2698ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2699ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
2700ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
270116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2702ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
2703ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
2704ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
2705b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
2706ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
2707ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
2708ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2709b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2710ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
2711ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
2712ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
27131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
2714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
27151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
2716515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2717515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2718b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2719515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2720515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
2721515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
2722515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2723515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2724515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2725515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
27261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
2727515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
27281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
27296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
27306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
27316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
27326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
27336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
27346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
27356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
27366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
27376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
27386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
27396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
27406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
27416469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
27426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
2744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
2745b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
27476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
27486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
27496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
27506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
27516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
2752642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
2753642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
2754642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
2755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2756515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2757515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
27581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
2759515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
27601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
276118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2762515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2763515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
276438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
276558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
2766b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
276758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
27689e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
2769515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2770515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
2771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2772515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
277318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2774b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2776515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
2777515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
2778515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
27811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
2782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
27831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
278418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2785515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
2786515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
278718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
278858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
2789b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
279058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
2791b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
2792515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
2793515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
2794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
2795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
279618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
2797b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
2798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
279932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
2800bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (!isThumb()) {
2801ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
2802bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2803bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
280432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
2805bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    if (isThumb()) {
2806ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
2807bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
2808bd27f5adbd8f3b8ab8def5aa43fbc406ac9b8cbeEvan Cheng    }
2809eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
28102a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
2811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
2812515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
2813515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
281490b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
281590b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
28169c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
2817ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
281894b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
281994b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
282090b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
2821ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
28223483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
28230692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
28240692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
28253483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
2826