ARMAsmParser.cpp revision 98447daa9559d5bf7816f084581b5ca073d316f6
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"
217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrDesc.h"
2294b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCRegisterInfo.h"
23ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng#include "llvm/MC/MCSubtargetInfo.h"
2494b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h"
2589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach#include "llvm/Support/MathExtras.h"
26c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/Support/SourceMgr.h"
273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
28fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar#include "llvm/Support/raw_ostream.h"
2911e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach#include "llvm/ADT/BitVector.h"
3075ca4b94bd9dcd3952fdc237429342a2154ba142Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
3194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/ADT/STLExtras.h"
32c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/SmallVector.h"
330c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson#include "llvm/ADT/StringExtras.h"
34345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar#include "llvm/ADT/StringSwitch.h"
35c6ef277a0b8f43af22d86aea9d5053749cacfbbbChris Lattner#include "llvm/ADT/Twine.h"
36ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
37ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyusing namespace llvm;
38ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
393a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
40146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
41146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand;
4216c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
4394b9550a32d189704a8eae55505edf62662c0534Evan Chengclass ARMAsmParser : public MCTargetAsmParser {
44ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  MCSubtargetInfo &STI;
45ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &Parser;
46ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
47f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  struct {
48f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ARMCC::CondCodes Cond;    // Condition for IT block.
49f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Mask:4;          // Condition mask for instructions.
50f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Starting at first 1 (from lsb).
51f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '1'  condition as indicated in IT.
52f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              //   '0'  inverse of condition (else).
53f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // Count of instructions in IT block is
54f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // 4 - trailingzeroes(mask)
55f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
56f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    bool FirstCond;           // Explicit flag for when we're parsing the
57f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // First instruction in the IT block. It's
58f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // implied in the mask, so needs special
59f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // handling.
60f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
61f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned CurPosition;     // Current position in parsing of IT
62f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // block. In range [0,3]. Initialized
63f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // according to count of instructions in block.
64f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                              // ~0U if no active IT block.
65f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } ITState;
66f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  bool inITBlock() { return ITState.CurPosition != ~0U;}
67a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  void forwardITPosition() {
68a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (!inITBlock()) return;
69a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Move to the next instruction in the IT block, if there is one. If not,
70a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // mark the block as done.
71a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    unsigned TZ = CountTrailingZeros_32(ITState.Mask);
72a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (++ITState.CurPosition == 5 - TZ)
73a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      ITState.CurPosition = ~0U; // Done with the IT block after this.
74a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach  }
75f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
76f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
77ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmParser &getParser() const { return Parser; }
78ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
79ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
80ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
81ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
82ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int tryParseRegister();
841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool tryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
850d87ec21d79c8622733b8367aa41067169602480Jim Grosbach  int tryParseShiftRegister(SmallVectorImpl<MCParsedAsmOperand*> &);
861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
891355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parsePrefix(ARMMCExpr::VariantKind &RefKind);
901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  const MCExpr *applyPrefixToExpr(const MCExpr *E,
919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                  MCSymbolRefExpr::VariantKind Variant);
929081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
93a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool parseMemRegOffsetShift(ARM_AM::ShiftOpc &ShiftType,
957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                              unsigned &ShiftAmount);
961355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveWord(unsigned Size, SMLoc L);
971355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumb(SMLoc L);
981355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveThumbFunc(SMLoc L);
991355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveCode(SMLoc L);
1001355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool parseDirectiveSyntax(SMLoc L);
101515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
1021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
10389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          bool &CarrySetting, unsigned &ProcessorIMod,
10489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                          StringRef &ITMask);
1051355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  void getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
106fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                             bool &CanAcceptPredicationCode);
10716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
108ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumb() const {
109ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // FIXME: Can tablegen auto-generate this?
110ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
111ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
112ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  bool isThumbOne() const {
113ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
114ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
11547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  bool isThumbTwo() const {
11647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
11747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
118194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  bool hasV6Ops() const {
119194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return STI.getFeatureBits() & ARM::HasV6Ops;
120194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  }
12132869205052430f45d598fba25ab878d8b29da2dEvan Cheng  void SwitchMode() {
122ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
123ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(FB);
12432869205052430f45d598fba25ab878d8b29da2dEvan Cheng  }
125ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng
126a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// @name Auto-generated Match Functions
127a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// {
1283483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
1290692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_ASSEMBLER_HEADER
1300692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#include "ARMGenAsmMatcher.inc"
131a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
132a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  /// }
133a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
13489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  OperandMatchResultTy parseITCondCode(SmallVectorImpl<MCParsedAsmOperand*>&);
13543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocNumOperand(
136f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
13743904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseCoprocRegOperand(
138f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    SmallVectorImpl<MCParsedAsmOperand*>&);
13943904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMemBarrierOptOperand(
1408bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14143904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseProcIFlagsOperand(
1428bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
14343904299b05bdf579415749041f77c4490fe5f5bJim Grosbach  OperandMatchResultTy parseMSRMaskOperand(
1448bba1a5ef0f8a71de2e58c7f05b8714a73464ca8Bruno Cardoso Lopes    SmallVectorImpl<MCParsedAsmOperand*>&);
145f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &O,
146f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach                                   StringRef Op, int Low, int High);
147f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHLSLImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
148f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "lsl", 0, 31);
149f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
150f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
151f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return parsePKHImm(O, "asr", 1, 32);
152f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
153c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
154580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  OperandMatchResultTy parseShifterImm(SmallVectorImpl<MCParsedAsmOperand*>&);
1557e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  OperandMatchResultTy parseRotImm(SmallVectorImpl<MCParsedAsmOperand*>&);
156293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  OperandMatchResultTy parseBitfield(SmallVectorImpl<MCParsedAsmOperand*>&);
1577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
158251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
159ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
160ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Asm Match Converter Methods
1611355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
162ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1639ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  bool cvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
1649ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
165548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  bool cvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
166548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1671355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool cvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
168ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1697b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  bool cvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
1707b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
1717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
1767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool cvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
1787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                             const SmallVectorImpl<MCParsedAsmOperand*> &);
1792fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
1802fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
18114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
18214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                  const SmallVectorImpl<MCParsedAsmOperand*> &);
183623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
184623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                                  const SmallVectorImpl<MCParsedAsmOperand*> &);
18588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  bool cvtThumbMultiply(MCInst &Inst, unsigned Opcode,
18688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach                        const SmallVectorImpl<MCParsedAsmOperand*> &);
187189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
188189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  bool validateInstruction(MCInst &Inst,
189189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
190f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  void processInstruction(MCInst &Inst,
191f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                          const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
192d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  bool shouldOmitCCOutOperand(StringRef Mnemonic,
193d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                              SmallVectorImpl<MCParsedAsmOperand*> &Operands);
194189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
195ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbypublic:
19647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  enum ARMMatchResultTy {
197194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
198f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Match_RequiresNotITBlock,
199194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresV6,
200194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    Match_RequiresThumb2
20147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  };
20247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
203ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng  ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
20494b9550a32d189704a8eae55505edf62662c0534Evan Cheng    : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
205ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    MCAsmParserExtension::Initialize(_Parser);
20632869205052430f45d598fba25ab878d8b29da2dEvan Cheng
207ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng    // Initialize the set of available features.
208ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
209f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
210f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Not in an ITBlock to start with.
211f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = ~0U;
212ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  }
213ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
2141355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  // Implementation of the MCTargetAsmParser interface:
2151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
2161355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
217189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
2181355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool ParseDirective(AsmToken DirectiveID);
2191355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach
22047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  unsigned checkTargetMatchPredicate(MCInst &Inst);
22147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
2221355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  bool MatchAndEmitInstruction(SMLoc IDLoc,
2231355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2241355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach                               MCStreamer &Out);
225ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby};
22616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach} // end anonymous namespace
22716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2283a69756e392942bc522193f38d7f33958ed3b131Chris Lattnernamespace {
2293a69756e392942bc522193f38d7f33958ed3b131Chris Lattner
230a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// ARMOperand - Instances of this class represent a parsed ARM machine
231a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby/// instruction.
232146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingclass ARMOperand : public MCParsedAsmOperand {
233762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  enum KindTy {
2348462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    CondCode,
235d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    CCOut,
23689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITCondMask,
237fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocNum,
238fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    CoprocReg,
239cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    Immediate,
240706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    MemBarrierOpt,
2418462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Memory,
2427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    PostIndexRegister,
243584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    MSRMask,
244a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ProcIFlags,
2458462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Register,
2468d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    RegisterList,
2470f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    DPRRegisterList,
2480f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    SPRRegisterList,
249e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftedRegister,
25092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ShiftedImmediate,
251580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ShifterImmediate,
2527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    RotateImmediate,
253293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    BitfieldDescriptor,
2548462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Token
255a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  } Kind;
256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
257762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc StartLoc, EndLoc;
25824d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling  SmallVector<unsigned, 8> Registers;
259a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
260a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  union {
261a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
2628462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      ARMCC::CondCodes Val;
2638462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    } CC;
2648462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
2658462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    struct {
266fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      unsigned Val;
267fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    } Cop;
268fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
269fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    struct {
27089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      unsigned Mask:4;
27189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } ITMask;
27289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
27389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
27489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ARM_MB::MemBOpt Val;
27589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } MBOpt;
27689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
27789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    struct {
278a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ARM_PROC::IFlags Val;
279a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    } IFlags;
280a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
281a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    struct {
282584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Val;
283584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    } MMask;
284584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
285584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    struct {
286a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      const char *Data;
287a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned Length;
288a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Tok;
289a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
290a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
291a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned RegNum;
292a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Reg;
293a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2948155e5b753aca42973cf317727f3805faddcaf90Bill Wendling    struct {
295cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby      const MCExpr *Val;
296cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    } Imm;
29716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
2986a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    /// Combined record for all forms of ARM address expressions.
299a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    struct {
300a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      unsigned BaseRegNum;
3017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Offset is in OffsetReg or OffsetImm. If both are zero, no offset
3027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // was specified.
3037ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      const MCConstantExpr *OffsetImm;  // Offset immediate value
3047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned OffsetRegNum;    // Offset register num, when OffsetImm == NULL
3057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::ShiftOpc ShiftType; // Shift type for OffsetReg
3060d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      unsigned ShiftImm;      // shift for OffsetReg.
3077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned isNegative : 1;  // Negated OffsetReg? (~'U' bit)
308a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    } Mem;
3090082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
3100082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    struct {
3117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      unsigned RegNum;
312f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      bool isAdd;
313f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      ARM_AM::ShiftOpc ShiftTy;
314f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      unsigned ShiftImm;
3157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } PostIdxReg;
3167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
3177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    struct {
318580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      bool isASR;
319e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned Imm;
320580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    } ShifterImm;
321e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    struct {
322e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      ARM_AM::ShiftOpc ShiftTy;
323e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned SrcReg;
324e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftReg;
325e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      unsigned ShiftImm;
326af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedReg;
32792a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    struct {
32892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      ARM_AM::ShiftOpc ShiftTy;
32992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned SrcReg;
33092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      unsigned ShiftImm;
331af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    } RegShiftedImm;
3327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    struct {
3337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      unsigned Imm;
3347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    } RotImm;
335293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    struct {
336293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned LSB;
337293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      unsigned Width;
338293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    } Bitfield;
339a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  };
34016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
341146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
342146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendlingpublic:
343762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  ARMOperand(const ARMOperand &o) : MCParsedAsmOperand() {
344762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Kind = o.Kind;
345762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    StartLoc = o.StartLoc;
346762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    EndLoc = o.EndLoc;
347762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    switch (Kind) {
3488462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    case CondCode:
3498462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      CC = o.CC;
3508462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      break;
35189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    case ITCondMask:
35289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      ITMask = o.ITMask;
35389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      break;
354762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Token:
3558462b30548fb5969250858036638c73c16b65b43Daniel Dunbar      Tok = o.Tok;
356762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
357d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    case CCOut:
358762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Register:
359762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Reg = o.Reg;
360762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
3618d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    case RegisterList:
3620f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case DPRRegisterList:
3630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    case SPRRegisterList:
36424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Registers = o.Registers;
3658d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling      break;
366fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocNum:
367fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    case CoprocReg:
368fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      Cop = o.Cop;
369fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes      break;
370762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Immediate:
371762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Imm = o.Imm;
372762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
373706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    case MemBarrierOpt:
374706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      MBOpt = o.MBOpt;
375706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes      break;
376762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    case Memory:
377762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      Mem = o.Mem;
378762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan      break;
3797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    case PostIndexRegister:
3807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      PostIdxReg = o.PostIdxReg;
3817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      break;
382584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    case MSRMask:
383584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      MMask = o.MMask;
384584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      break;
385a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    case ProcIFlags:
386a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      IFlags = o.IFlags;
3870082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
388580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    case ShifterImmediate:
389580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      ShifterImm = o.ShifterImm;
3900082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      break;
391e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    case ShiftedRegister:
392af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedReg = o.RegShiftedReg;
393e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      break;
39492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    case ShiftedImmediate:
395af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      RegShiftedImm = o.RegShiftedImm;
39692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson      break;
3977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    case RotateImmediate:
3987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      RotImm = o.RotImm;
3997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach      break;
400293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    case BitfieldDescriptor:
401293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      Bitfield = o.Bitfield;
402293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach      break;
403762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
404762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  }
40516c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
406762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getStartLoc - Get the location of the first token of this operand.
407762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getStartLoc() const { return StartLoc; }
408762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  /// getEndLoc - Get the location of the last token of this operand.
409762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc getEndLoc() const { return EndLoc; }
410a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4118462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  ARMCC::CondCodes getCondCode() const {
4128462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    assert(Kind == CondCode && "Invalid access!");
4138462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    return CC.Val;
4148462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
4158462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
416fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  unsigned getCoproc() const {
417fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
418fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Cop.Val;
419fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
420fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
421a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  StringRef getToken() const {
422a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(Kind == Token && "Invalid access!");
423a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return StringRef(Tok.Data, Tok.Length);
424a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
425a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
426a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  unsigned getReg() const {
4276aa49435994c33257b7588cac24671785d17fa6eBenjamin Kramer    assert((Kind == Register || Kind == CCOut) && "Invalid access!");
4287729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    return Reg.RegNum;
429a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
430a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
4315fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  const SmallVectorImpl<unsigned> &getRegList() const {
4320f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    assert((Kind == RegisterList || Kind == DPRRegisterList ||
4330f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling            Kind == SPRRegisterList) && "Invalid access!");
43424d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling    return Registers;
4358d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
4368d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
437cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  const MCExpr *getImm() const {
438cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    assert(Kind == Immediate && "Invalid access!");
439cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby    return Imm.Val;
440cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
441cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
442706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  ARM_MB::MemBOpt getMemBarrierOpt() const {
443706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(Kind == MemBarrierOpt && "Invalid access!");
444706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return MBOpt.Val;
445706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
446706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
447a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ARM_PROC::IFlags getProcIFlags() const {
448a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(Kind == ProcIFlags && "Invalid access!");
449a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return IFlags.Val;
450a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
451a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
452584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned getMSRMask() const {
453584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(Kind == MSRMask && "Invalid access!");
454584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MMask.Val;
455584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
456584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
457fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocNum() const { return Kind == CoprocNum; }
458fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  bool isCoprocReg() const { return Kind == CoprocReg; }
4598462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  bool isCondCode() const { return Kind == CondCode; }
460d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  bool isCCOut() const { return Kind == CCOut; }
46189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  bool isITMask() const { return Kind == ITCondMask; }
46289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  bool isITCondCode() const { return Kind == CondCode; }
4633483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  bool isImm() const { return Kind == Immediate; }
46472f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_1020s4() const {
46572f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (Kind != Immediate)
46672f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
46772f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
46872f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
46972f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
47072f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 1020;
47172f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
47272f39f8436848885176943b0ba985a7171145423Jim Grosbach  bool isImm0_508s4() const {
47372f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (Kind != Immediate)
47472f39f8436848885176943b0ba985a7171145423Jim Grosbach      return false;
47572f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
47672f39f8436848885176943b0ba985a7171145423Jim Grosbach    if (!CE) return false;
47772f39f8436848885176943b0ba985a7171145423Jim Grosbach    int64_t Value = CE->getValue();
47872f39f8436848885176943b0ba985a7171145423Jim Grosbach    return ((Value & 3) == 0) && Value >= 0 && Value <= 508;
47972f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
4806b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isImm0_255() const {
4816b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
4826b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
4836b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
4846b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
4856b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
4866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return Value >= 0 && Value < 256;
4876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
48883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_7() const {
48983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
49083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
49183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
49283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
49383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
49483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 8;
49583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
49683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  bool isImm0_15() const {
49783ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (Kind != Immediate)
49883ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach      return false;
49983ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
50083ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    if (!CE) return false;
50183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    int64_t Value = CE->getValue();
50283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    return Value >= 0 && Value < 16;
50383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
5047c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  bool isImm0_31() const {
5057c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (Kind != Immediate)
5067c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach      return false;
5077c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5087c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    if (!CE) return false;
5097c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    int64_t Value = CE->getValue();
5107c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    return Value >= 0 && Value < 32;
5117c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
512f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  bool isImm1_16() const {
513f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (Kind != Immediate)
514f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach      return false;
515f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
516f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    if (!CE) return false;
517f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    int64_t Value = CE->getValue();
518f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    return Value > 0 && Value < 17;
519f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
5204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  bool isImm1_32() const {
5214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (Kind != Immediate)
5224a5ffb399f841783c201c599b88d576757f1922eJim Grosbach      return false;
5234a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5244a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    if (!CE) return false;
5254a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    int64_t Value = CE->getValue();
5264a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    return Value > 0 && Value < 33;
5274a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
528fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  bool isImm0_65535() const {
529fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (Kind != Immediate)
530fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach      return false;
531fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
532fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    if (!CE) return false;
533fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    int64_t Value = CE->getValue();
534fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    return Value >= 0 && Value < 65536;
535fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
536ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  bool isImm0_65535Expr() const {
537ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (Kind != Immediate)
538ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach      return false;
539ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
540ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // If it's not a constant expression, it'll generate a fixup and be
541ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    // handled later.
542ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    if (!CE) return true;
543ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    int64_t Value = CE->getValue();
544ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Value >= 0 && Value < 65536;
545ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
546ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  bool isImm24bit() const {
547ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (Kind != Immediate)
548ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach      return false;
549ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
550ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    if (!CE) return false;
551ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    int64_t Value = CE->getValue();
552ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    return Value >= 0 && Value <= 0xffffff;
553ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
55470939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  bool isImmThumbSR() const {
55570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (Kind != Immediate)
55670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach      return false;
55770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
55870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    if (!CE) return false;
55970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    int64_t Value = CE->getValue();
56070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    return Value > 0 && Value < 33;
56170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
562f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHLSLImm() const {
563f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
564f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
565f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
566f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
567f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
568f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value >= 0 && Value < 32;
569f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
570f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  bool isPKHASRImm() const {
571f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (Kind != Immediate)
572f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach      return false;
573f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
574f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    if (!CE) return false;
575f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int64_t Value = CE->getValue();
576f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return Value > 0 && Value <= 32;
577f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
5786bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  bool isARMSOImm() const {
5796bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (Kind != Immediate)
5806bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach      return false;
5816bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5826bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    if (!CE) return false;
5836bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    int64_t Value = CE->getValue();
5846bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    return ARM_AM::getSOImmVal(Value) != -1;
5856bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
5866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  bool isT2SOImm() const {
5876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (Kind != Immediate)
5886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach      return false;
5896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
5906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    if (!CE) return false;
5916b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    int64_t Value = CE->getValue();
5926b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    return ARM_AM::getT2SOImmVal(Value) != -1;
5936b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
594c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  bool isSetEndImm() const {
595c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (Kind != Immediate)
596c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      return false;
597c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
598c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    if (!CE) return false;
599c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    int64_t Value = CE->getValue();
600c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Value == 1 || Value == 0;
601c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
602b32e7844e9f79d2bd4ff34a1d19aba347f999abcBill Wendling  bool isReg() const { return Kind == Register; }
6038d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  bool isRegList() const { return Kind == RegisterList; }
6040f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isDPRRegList() const { return Kind == DPRRegisterList; }
6050f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  bool isSPRRegList() const { return Kind == SPRRegisterList; }
60614b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isToken() const { return Kind == Token; }
607706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  bool isMemBarrierOpt() const { return Kind == MemBarrierOpt; }
60814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  bool isMemory() const { return Kind == Memory; }
609580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isShifterImm() const { return Kind == ShifterImmediate; }
610af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedReg() const { return Kind == ShiftedRegister; }
611af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  bool isRegShiftedImm() const { return Kind == ShiftedImmediate; }
6127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  bool isRotImm() const { return Kind == RotateImmediate; }
613293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  bool isBitfield() const { return Kind == BitfieldDescriptor; }
614f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxRegShifted() const { return Kind == PostIndexRegister; }
615f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  bool isPostIdxReg() const {
616f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    return Kind == PostIndexRegister && PostIdxReg.ShiftTy == ARM_AM::no_shift;
617f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
6187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemNoOffset() const {
6197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
620ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes      return false;
6217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // No offset of any kind.
6227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Mem.OffsetRegNum == 0 && Mem.OffsetImm == 0;
623ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
6247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode2() const {
6257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
626ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
6277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
6287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return true;
6297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
6307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -4096 && Val < 4096;
6337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
634039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  bool isAM2OffsetImm() const {
635039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Kind != Immediate)
636039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach      return false;
637039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Immediate offset in range [-4095, 4095].
638039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
639039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (!CE) return false;
640039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int64_t Val = CE->getValue();
641039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    return Val > -4096 && Val < 4096;
642039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
6432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAddrMode3() const {
6442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind != Memory)
6452fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
6462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // No shifts are legal for AM3.
6472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.ShiftType != ARM_AM::no_shift) return false;
6482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Check for register offset.
6492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Mem.OffsetRegNum) return true;
6502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetImm) return true;
6522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    return Val > -256 && Val < 256;
6542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
6552fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  bool isAM3Offset() const {
6562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind != Immediate && Kind != PostIndexRegister)
6572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return false;
6582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind == PostIndexRegister)
6592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      return PostIdxReg.ShiftTy == ARM_AM::no_shift;
6602fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Immediate offset in range [-255, 255].
6612fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
6622fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!CE) return false;
6632fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int64_t Val = CE->getValue();
664251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Special case, #-0 is INT32_MIN.
665251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return (Val > -256 && Val < 256) || Val == INT32_MIN;
6662fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
6677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isAddrMode5() const {
6687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory)
669ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
6707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Check for register offset.
6717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Mem.OffsetRegNum) return false;
6727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-1020, 1020] and a multiple of 4.
6737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
6747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
6750da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
6760da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson           Val == INT32_MIN;
6777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
6787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemRegOffset() const {
6797ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum)
680ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes      return false;
681ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes    return true;
682ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
6837ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemThumbRR() const {
6847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Thumb reg+reg addressing is simple. Just two registers, a base and
6857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // an offset. No shifts, negations or any other complicating factors.
6867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
6877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        Mem.ShiftType != ARM_AM::no_shift)
68887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling      return false;
68960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    return isARMLowRegister(Mem.BaseRegNum) &&
69060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      (!Mem.OffsetRegNum || isARMLowRegister(Mem.OffsetRegNum));
69160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
69260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  bool isMemThumbRIs4() const {
69360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
69460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
69560f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach      return false;
69660f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 124].
69760f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    if (!Mem.OffsetImm) return true;
69860f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
699ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 124 && (Val % 4) == 0;
700ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
70138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  bool isMemThumbRIs2() const {
70238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
70338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
70438466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach      return false;
70538466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    // Immediate offset, multiple of 4 in range [0, 62].
70638466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    if (!Mem.OffsetImm) return true;
70738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
70838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    return Val >= 0 && Val <= 62 && (Val % 2) == 0;
70938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
71048ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  bool isMemThumbRIs1() const {
71148ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 ||
71248ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach        !isARMLowRegister(Mem.BaseRegNum))
71348ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach      return false;
71448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    // Immediate offset in range [0, 31].
71548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    if (!Mem.OffsetImm) return true;
71648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
71748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    return Val >= 0 && Val <= 31;
71848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
719ecd858968384be029574d845eb098d357049e02eJim Grosbach  bool isMemThumbSPI() const {
720ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0 || Mem.BaseRegNum != ARM::SP)
721ecd858968384be029574d845eb098d357049e02eJim Grosbach      return false;
722ecd858968384be029574d845eb098d357049e02eJim Grosbach    // Immediate offset, multiple of 4 in range [0, 1020].
723ecd858968384be029574d845eb098d357049e02eJim Grosbach    if (!Mem.OffsetImm) return true;
724ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
725ecd858968384be029574d845eb098d357049e02eJim Grosbach    return Val >= 0 && Val <= 1020 && (Val % 4) == 0;
726505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
7277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm8Offset() const {
7287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
729f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling      return false;
7307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-255, 255].
7317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
7327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
7337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Val > -256 && Val < 256;
734f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
7357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isMemImm12Offset() const {
73609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If we have an immediate that's not a constant, treat it as a label
73709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // reference needing a fixup. If it is a constant, it's something else
73809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // and we reject it.
73909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    if (Kind == Immediate && !isa<MCConstantExpr>(getImm()))
74009176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return true;
74109176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
7427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Memory || Mem.OffsetRegNum != 0)
743ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling      return false;
7447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Immediate offset in range [-4095, 4095].
7457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetImm) return true;
7467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm->getValue();
7470da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    return (Val > -4096 && Val < 4096) || (Val == INT32_MIN);
7487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
7497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isPostIdxImm8() const {
7507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Kind != Immediate)
7517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return false;
7527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
753ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling    if (!CE) return false;
7547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = CE->getValue();
75563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    return (Val > -256 && Val < 256) || (Val == INT32_MIN);
756ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
7577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
758584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  bool isMSRMask() const { return Kind == MSRMask; }
759a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  bool isProcIFlags() const { return Kind == ProcIFlags; }
7603483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
7613483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
76214b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    // Add as immediates when possible.  Null MCExpr = 0.
76314b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    if (Expr == 0)
76414b93851cc7611ae6c2000f1c162592ead954420Chris Lattner      Inst.addOperand(MCOperand::CreateImm(0));
76514b93851cc7611ae6c2000f1c162592ead954420Chris Lattner    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
7663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
7673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    else
7683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar      Inst.addOperand(MCOperand::CreateExpr(Expr));
7693483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
7703483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
7718462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
772345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    assert(N == 2 && "Invalid number of operands!");
7738462b30548fb5969250858036638c73c16b65b43Daniel Dunbar    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
77404f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    unsigned RegNum = getCondCode() == ARMCC::AL ? 0: ARM::CPSR;
77504f74942f2994a7c1d8e62c207c4005ed4652b6aJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegNum));
7768462b30548fb5969250858036638c73c16b65b43Daniel Dunbar  }
7778462b30548fb5969250858036638c73c16b65b43Daniel Dunbar
778fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
779fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
780fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
781fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
782fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
78389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITMaskOperands(MCInst &Inst, unsigned N) const {
78489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
78589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(ITMask.Mask));
78689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
78789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
78889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  void addITCondCodeOperands(MCInst &Inst, unsigned N) const {
78989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
79089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(unsigned(getCondCode())));
79189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
79289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
793fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
794fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
795fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
796fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
797fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
798d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  void addCCOutOperands(MCInst &Inst, unsigned N) const {
799d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
800d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(getReg()));
801d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
802d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
803a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  void addRegOperands(MCInst &Inst, unsigned N) const {
804a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    assert(N == 1 && "Invalid number of operands!");
805a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    Inst.addOperand(MCOperand::CreateReg(getReg()));
806a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
807a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
808af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedRegOperands(MCInst &Inst, unsigned N) const {
809e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    assert(N == 3 && "Invalid number of operands!");
810af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedReg() && "addRegShiftedRegOperands() on non RegShiftedReg!");
811af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.SrcReg));
812af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedReg.ShiftReg));
813e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Inst.addOperand(MCOperand::CreateImm(
814af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedReg.ShiftTy, RegShiftedReg.ShiftImm)));
815e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
816e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
817af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach  void addRegShiftedImmOperands(MCInst &Inst, unsigned N) const {
818152d4a4bb6b75de740b4b8a9f48abb9069d50c17Owen Anderson    assert(N == 2 && "Invalid number of operands!");
819af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    assert(isRegShiftedImm() && "addRegShiftedImmOperands() on non RegShiftedImm!");
820af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
82192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Inst.addOperand(MCOperand::CreateImm(
822af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach      ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
82392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
82492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
82592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
826580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  void addShifterImmOperands(MCInst &Inst, unsigned N) const {
8270082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    assert(N == 1 && "Invalid number of operands!");
828580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
829580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach                                         ShifterImm.Imm));
8300082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
8310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
83287f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  void addRegListOperands(MCInst &Inst, unsigned N) const {
8337729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    assert(N == 1 && "Invalid number of operands!");
8345fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
8355fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
8367729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ++I)
8377729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      Inst.addOperand(MCOperand::CreateReg(*I));
83887f4f9a946549ad93046990a364ac5190333a7ebBill Wendling  }
83987f4f9a946549ad93046990a364ac5190333a7ebBill Wendling
8400f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addDPRRegListOperands(MCInst &Inst, unsigned N) const {
8410f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
8420f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
8430f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
8440f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  void addSPRRegListOperands(MCInst &Inst, unsigned N) const {
8450f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    addRegListOperands(Inst, N);
8460f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  }
8470f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
8487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  void addRotImmOperands(MCInst &Inst, unsigned N) const {
8497e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8507e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    // Encoded as val>>3. The printer handles display as 8, 16, 24.
8517e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(RotImm.Imm >> 3));
8527e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
8537e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
854293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  void addBitfieldOperands(MCInst &Inst, unsigned N) const {
855293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
856293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Munge the lsb/width into a bitfield mask.
857293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned lsb = Bitfield.LSB;
858293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    unsigned width = Bitfield.Width;
859293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    // Make a 32-bit mask w/ the referenced bits clear and all other bits set.
860293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    uint32_t Mask = ~(((uint32_t)0xffffffff >> lsb) << (32 - width) >>
861293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                      (32 - (lsb + width)));
862293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Mask));
863293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
864293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
8653483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  void addImmOperands(MCInst &Inst, unsigned N) const {
8666b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8676b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
8686b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
8696b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
87072f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_1020s4Operands(MCInst &Inst, unsigned N) const {
87172f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
87272f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
87372f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
87472f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
87572f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
87672f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
87772f39f8436848885176943b0ba985a7171145423Jim Grosbach
87872f39f8436848885176943b0ba985a7171145423Jim Grosbach  void addImm0_508s4Operands(MCInst &Inst, unsigned N) const {
87972f39f8436848885176943b0ba985a7171145423Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
88072f39f8436848885176943b0ba985a7171145423Jim Grosbach    // The immediate is scaled by four in the encoding and is stored
88172f39f8436848885176943b0ba985a7171145423Jim Grosbach    // in the MCInst as such. Lop off the low two bits here.
88272f39f8436848885176943b0ba985a7171145423Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
88372f39f8436848885176943b0ba985a7171145423Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
88472f39f8436848885176943b0ba985a7171145423Jim Grosbach  }
88572f39f8436848885176943b0ba985a7171145423Jim Grosbach
8866b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addImm0_255Operands(MCInst &Inst, unsigned N) const {
8876b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8886b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach    addExpr(Inst, getImm());
8896b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  }
8906b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach
89183ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_7Operands(MCInst &Inst, unsigned N) const {
89283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
89383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
89483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
89583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
89683ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  void addImm0_15Operands(MCInst &Inst, unsigned N) const {
8977c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
8987c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach    addExpr(Inst, getImm());
8997c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  }
9007c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach
9017c6e42e9273168ba9b1273a1580d569e1bac0e91Jim Grosbach  void addImm0_31Operands(MCInst &Inst, unsigned N) const {
90283ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
90383ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach    addExpr(Inst, getImm());
90483ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach  }
90583ab070fc1fbb02ca77b0a37e6ae0eacf58001e1Jim Grosbach
906f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  void addImm1_16Operands(MCInst &Inst, unsigned N) const {
907f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    assert(N == 1 && "Invalid number of operands!");
908f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
909f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    // the bits as encoded, so subtract off one here.
910f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
911f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
912f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach  }
913f49433523e8a39db6d83503e312ae55160eed90aJim Grosbach
9144a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  void addImm1_32Operands(MCInst &Inst, unsigned N) const {
9154a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    assert(N == 1 && "Invalid number of operands!");
9164a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // The constant encodes as the immediate-1, and we store in the instruction
9174a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    // the bits as encoded, so subtract off one here.
9184a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
9194a5ffb399f841783c201c599b88d576757f1922eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(CE->getValue() - 1));
9204a5ffb399f841783c201c599b88d576757f1922eJim Grosbach  }
9214a5ffb399f841783c201c599b88d576757f1922eJim Grosbach
922fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
923fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
924fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach    addExpr(Inst, getImm());
925fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach  }
926fff76ee7ef007b2bb74804f165fee475e30ead0dJim Grosbach
927ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  void addImm0_65535ExprOperands(MCInst &Inst, unsigned N) const {
928ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
929ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    addExpr(Inst, getImm());
930ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  }
931ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach
932ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach  void addImm24bitOperands(MCInst &Inst, unsigned N) const {
933ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    assert(N == 1 && "Invalid number of operands!");
934ed8384806e56952c44f8a717c1ef54a8468d2c8dJim Grosbach    addExpr(Inst, getImm());
93570939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  }
93670939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach
93770939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach  void addImmThumbSROperands(MCInst &Inst, unsigned N) const {
93870939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
93970939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // The constant encodes as the immediate, except for 32, which encodes as
94070939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    // zero.
94170939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
94270939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    unsigned Imm = CE->getValue();
94370939ee1415722d7f39f13faf9b3644b96007996Jim Grosbach    Inst.addOperand(MCOperand::CreateImm((Imm == 32 ? 0 : Imm)));
944ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
945ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
946f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHLSLImmOperands(MCInst &Inst, unsigned N) const {
947f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
948f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    addExpr(Inst, getImm());
949f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
950f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
951f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  void addPKHASRImmOperands(MCInst &Inst, unsigned N) const {
952f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
953f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // An ASR value of 32 encodes as 0, so that's how we want to add it to
954f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    // the instruction as well.
955f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
956f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    int Val = CE->getValue();
957f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val == 32 ? 0 : Val));
958f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
959f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
9606bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  void addARMSOImmOperands(MCInst &Inst, unsigned N) const {
9616bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    assert(N == 1 && "Invalid number of operands!");
9626bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach    addExpr(Inst, getImm());
9636bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach  }
9646bc1dbc37695bcfc5ae23a1a9e17550ee50fe02fJim Grosbach
9656b8f1e35eacba34a11e2a7d5f614efc47b43d2e3Jim Grosbach  void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
9663483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    assert(N == 1 && "Invalid number of operands!");
9673483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar    addExpr(Inst, getImm());
9683483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar  }
96916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
970c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
971c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
972c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    addExpr(Inst, getImm());
973c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
974c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
975706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
976706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
977706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
978706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
979706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
9807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
9817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
9827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
983505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes  }
984505f3cd2965e65b6b7ad023eaba0e3dc89b67409Bruno Cardoso Lopes
9857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode2Operands(MCInst &Inst, unsigned N) const {
9867ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
9877ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
9887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!Mem.OffsetRegNum) {
9897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
9907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // Special case for #-0
9917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val == INT32_MIN) Val = 0;
9927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      if (Val < 0) Val = -Val;
9937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
9947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    } else {
9957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // For register offset, we encode the shift type and negation flag
9967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      // here.
9977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
998dd32ba337aab88c215108ca8bf4a0267fce1e773Jim Grosbach                              Mem.ShiftImm, Mem.ShiftType);
999ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes    }
10007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
10027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1003ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  }
1004ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
1005039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  void addAM2OffsetImmOperands(MCInst &Inst, unsigned N) const {
1006039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1007039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1008039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    assert(CE && "non-constant AM2OffsetImm operand!");
1009039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    int32_t Val = CE->getValue();
1010039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
1011039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    // Special case for #-0
1012039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val == INT32_MIN) Val = 0;
1013039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    if (Val < 0) Val = -Val;
1014039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Val = ARM_AM::getAM2Opc(AddSub, Val, ARM_AM::no_shift);
1015039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
1016039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1017039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach  }
1018039c2e19c4237fb484315a62e95222ac28640bb7Jim Grosbach
10192fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAddrMode3Operands(MCInst &Inst, unsigned N) const {
10202fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
10212fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
10222fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (!Mem.OffsetRegNum) {
10232fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
10242fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // Special case for #-0
10252fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val == INT32_MIN) Val = 0;
10262fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      if (Val < 0) Val = -Val;
10272fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(AddSub, Val);
10282fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    } else {
10292fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // For register offset, we encode the shift type and negation flag
10302fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      // here.
10312fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Val = ARM_AM::getAM3Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add, 0);
10322fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
10332fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10342fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
10352fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10362fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
10372fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
10382fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  void addAM3OffsetOperands(MCInst &Inst, unsigned N) const {
10392fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10402fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Kind == PostIndexRegister) {
10412fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      int32_t Val =
10422fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach        ARM_AM::getAM3Opc(PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub, 0);
10432fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
10442fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(Val));
1045251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return;
10462fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    }
10472fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
10482fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Constant offset.
10492fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    const MCConstantExpr *CE = static_cast<const MCConstantExpr*>(getImm());
10502fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    int32_t Val = CE->getValue();
10512fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
10522fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    // Special case for #-0
10532fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val == INT32_MIN) Val = 0;
10542fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    if (Val < 0) Val = -Val;
1055251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Val = ARM_AM::getAM3Opc(AddSub, Val);
10562fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(0));
10572fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10582fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  }
10592fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
10607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addAddrMode5Operands(MCInst &Inst, unsigned N) const {
10617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The lower two bits are always zero and as such are not encoded.
10637ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int32_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() / 4 : 0;
10647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARM_AM::AddrOpc AddSub = Val < 0 ? ARM_AM::sub : ARM_AM::add;
10657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Special case for #-0
10667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val == INT32_MIN) Val = 0;
10677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Val < 0) Val = -Val;
10687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Val = ARM_AM::getAM5Opc(AddSub, Val);
10697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
10727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
10737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm8OffsetOperands(MCInst &Inst, unsigned N) const {
10747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
10757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
10767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1078ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  }
1079ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
10807ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemImm12OffsetOperands(MCInst &Inst, unsigned N) const {
10817ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
108209176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // If this is an immediate, it's a label reference.
108309176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    if (Kind == Immediate) {
108409176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      addExpr(Inst, getImm());
108509176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(0));
108609176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach      return;
108709176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    }
108809176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach
108909176e10dbe575b0f4c68803695c47ccb4b81f81Jim Grosbach    // Otherwise, it's a normal memory reg+offset.
10907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
10917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
10927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
10937ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
109492b5a2eb1646b3c1173a5ff3c0073f24ed5ee6a4Bill Wendling
10957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
10967ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 3 && "Invalid number of operands!");
10977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
10980d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                     Mem.ShiftImm, Mem.ShiftType);
10997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
11017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
11027ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
1103d3df5f32c059b3ac111f1c08571d5493aa1d48c6Daniel Dunbar
11047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
11057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
11067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
11077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
110814b93851cc7611ae6c2000f1c162592ead954420Chris Lattner  }
11093483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
111060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  void addMemThumbRIs4Operands(MCInst &Inst, unsigned N) const {
111160f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
111260f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
111360f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
111460f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
111548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  }
111648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach
111738466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  void addMemThumbRIs2Operands(MCInst &Inst, unsigned N) const {
111838466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
111938466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 2) : 0;
112038466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
112138466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
112238466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach  }
112338466309d5c8ce408f05567fa47aeaa3b5826080Jim Grosbach
112448ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach  void addMemThumbRIs1Operands(MCInst &Inst, unsigned N) const {
112548ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
112648ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue()) : 0;
112748ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
112848ff5ffe9e2a90f853ce3645b1b97ea7885eccf1Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
112960f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach  }
113060f91a3d9518617e29da18477ae433b8f0069304Jim Grosbach
1131ecd858968384be029574d845eb098d357049e02eJim Grosbach  void addMemThumbSPIOperands(MCInst &Inst, unsigned N) const {
1132ecd858968384be029574d845eb098d357049e02eJim Grosbach    assert(N == 2 && "Invalid number of operands!");
1133ecd858968384be029574d845eb098d357049e02eJim Grosbach    int64_t Val = Mem.OffsetImm ? (Mem.OffsetImm->getValue() / 4) : 0;
1134ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
1135ecd858968384be029574d845eb098d357049e02eJim Grosbach    Inst.addOperand(MCOperand::CreateImm(Val));
1136ecd858968384be029574d845eb098d357049e02eJim Grosbach  }
1137ecd858968384be029574d845eb098d357049e02eJim Grosbach
11387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxImm8Operands(MCInst &Inst, unsigned N) const {
11397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 1 && "Invalid number of operands!");
11407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
11417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(CE && "non-constant post-idx-imm8 operand!");
11427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int Imm = CE->getValue();
11437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    bool isAdd = Imm >= 0;
114463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (Imm == INT32_MIN) Imm = 0;
11457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Imm = (Imm < 0 ? -Imm : Imm) | (int)isAdd << 8;
11467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1147f4caf69720d807573c50d41aa06bcec1c99bdbbdBill Wendling  }
1148ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
11497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  void addPostIdxRegOperands(MCInst &Inst, unsigned N) const {
11507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
11517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1152f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(PostIdxReg.isAdd));
1153f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
1154f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
1155f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  void addPostIdxRegShiftedOperands(MCInst &Inst, unsigned N) const {
1156f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    assert(N == 2 && "Invalid number of operands!");
1157f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateReg(PostIdxReg.RegNum));
1158f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // The sign, shift type, and shift amount are encoded in a single operand
1159f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    // using the AM2 encoding helpers.
1160f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    ARM_AM::AddrOpc opc = PostIdxReg.isAdd ? ARM_AM::add : ARM_AM::sub;
1161f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    unsigned Imm = ARM_AM::getAM2Opc(opc, PostIdxReg.ShiftImm,
1162f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                     PostIdxReg.ShiftTy);
1163f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Inst.addOperand(MCOperand::CreateImm(Imm));
1164ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling  }
1165ef4a68badbde372faac9ca47efb9001def57a43dBill Wendling
1166584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  void addMSRMaskOperands(MCInst &Inst, unsigned N) const {
1167584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1168584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getMSRMask())));
1169584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1170584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1171a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  void addProcIFlagsOperands(MCInst &Inst, unsigned N) const {
1172a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    assert(N == 1 && "Invalid number of operands!");
1173a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
1174a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1175a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1176b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbach  virtual void print(raw_ostream &OS) const;
1177b3cb6967949493a2e1b10d015ac08b746736764eDaniel Dunbar
117889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {
117989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ARMOperand *Op = new ARMOperand(ITCondMask);
118089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->ITMask.Mask = Mask;
118189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->StartLoc = S;
118289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Op->EndLoc = S;
118389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return Op;
118489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
118589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
11863a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
11873a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(CondCode);
1188345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->CC.Val = CC;
1189345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->StartLoc = S;
1190345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar    Op->EndLoc = S;
11913a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1192345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  }
1193345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
1194fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
1195fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocNum);
1196fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1197fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1198fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1199fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1200fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1201fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1202fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
1203fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(CoprocReg);
1204fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->Cop.Val = CopVal;
1205fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->StartLoc = S;
1206fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    Op->EndLoc = S;
1207fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return Op;
1208fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  }
1209fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1210d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
1211d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    ARMOperand *Op = new ARMOperand(CCOut);
1212d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->Reg.RegNum = RegNum;
1213d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->StartLoc = S;
1214d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    Op->EndLoc = S;
1215d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    return Op;
1216d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  }
1217d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach
12183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateToken(StringRef Str, SMLoc S) {
12193a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Token);
1220762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Data = Str.data();
1221762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Tok.Length = Str.size();
1222762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1223762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = S;
12243a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1225a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1226a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
122750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  static ARMOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
12283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Register);
1229762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Reg.RegNum = RegNum;
1230762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1231762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
12323a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1233a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1234a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1235e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  static ARMOperand *CreateShiftedRegister(ARM_AM::ShiftOpc ShTy,
1236e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned SrcReg,
1237e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftReg,
1238e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           unsigned ShiftImm,
1239e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                                           SMLoc S, SMLoc E) {
1240e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ARMOperand *Op = new ARMOperand(ShiftedRegister);
1241af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftTy = ShTy;
1242af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.SrcReg = SrcReg;
1243af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftReg = ShiftReg;
1244af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedReg.ShiftImm = ShiftImm;
1245e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->StartLoc = S;
1246e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    Op->EndLoc = E;
1247e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Op;
1248e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1249e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
125092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
125192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned SrcReg,
125292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            unsigned ShiftImm,
125392a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                            SMLoc S, SMLoc E) {
125492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    ARMOperand *Op = new ARMOperand(ShiftedImmediate);
1255af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftTy = ShTy;
1256af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.SrcReg = SrcReg;
1257af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach    Op->RegShiftedImm.ShiftImm = ShiftImm;
125892a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->StartLoc = S;
125992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Op->EndLoc = E;
126092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    return Op;
126192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  }
126292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson
1263580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  static ARMOperand *CreateShifterImm(bool isASR, unsigned Imm,
12640082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                   SMLoc S, SMLoc E) {
1265580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    ARMOperand *Op = new ARMOperand(ShifterImmediate);
1266580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.isASR = isASR;
1267580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Op->ShifterImm.Imm = Imm;
12680082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->StartLoc = S;
12690082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    Op->EndLoc = E;
12700082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    return Op;
12710082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  }
12720082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
12737e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  static ARMOperand *CreateRotImm(unsigned Imm, SMLoc S, SMLoc E) {
12747e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    ARMOperand *Op = new ARMOperand(RotateImmediate);
12757e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->RotImm.Imm = Imm;
12767e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->StartLoc = S;
12777e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Op->EndLoc = E;
12787e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return Op;
12797e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
12807e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
1281293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  static ARMOperand *CreateBitfield(unsigned LSB, unsigned Width,
1282293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach                                    SMLoc S, SMLoc E) {
1283293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    ARMOperand *Op = new ARMOperand(BitfieldDescriptor);
1284293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.LSB = LSB;
1285293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->Bitfield.Width = Width;
1286293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->StartLoc = S;
1287293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Op->EndLoc = E;
1288293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return Op;
1289293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
1290293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
12917729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  static ARMOperand *
12925fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  CreateRegList(const SmallVectorImpl<std::pair<unsigned, SMLoc> > &Regs,
1293cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay                SMLoc StartLoc, SMLoc EndLoc) {
12940f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    KindTy Kind = RegisterList;
12950f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
1296275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng    if (llvm::ARMMCRegisterClasses[ARM::DPRRegClassID].
1297275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng        contains(Regs.front().first))
12980f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = DPRRegisterList;
1299275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng    else if (llvm::ARMMCRegisterClasses[ARM::SPRRegClassID].
1300275944afb55086d0b4b20d4d831de7c1c7507925Evan Cheng             contains(Regs.front().first))
13010f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling      Kind = SPRRegisterList;
13020f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling
13030f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling    ARMOperand *Op = new ARMOperand(Kind);
13045fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<std::pair<unsigned, SMLoc> >::const_iterator
13057729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = Regs.begin(), E = Regs.end(); I != E; ++I)
130624d22d27640e9de954a5ac26f51a45cc96bb9135Bill Wendling      Op->Registers.push_back(I->first);
1307cb21d1c9fd1cf53f063183f7eb28af7fa4052ef0Bill Wendling    array_pod_sort(Op->Registers.begin(), Op->Registers.end());
1308cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->StartLoc = StartLoc;
1309cc8d10e1a8a8555fa63f33e36e3c1ed2fb24389dMatt Beaumont-Gay    Op->EndLoc = EndLoc;
13108d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    return Op;
13118d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
13128d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
13133a69756e392942bc522193f38d7f33958ed3b131Chris Lattner  static ARMOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
13143a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Immediate);
1315762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Imm.Val = Val;
1316762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1317762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
13183a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1319cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby  }
1320cfe072401658bbe9336b200b79526b65c5213b74Kevin Enderby
13217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  static ARMOperand *CreateMem(unsigned BaseRegNum,
13227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               const MCConstantExpr *OffsetImm,
13237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               unsigned OffsetRegNum,
13247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               ARM_AM::ShiftOpc ShiftType,
13250d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                               unsigned ShiftImm,
13267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                               bool isNegative,
13273a69756e392942bc522193f38d7f33958ed3b131Chris Lattner                               SMLoc S, SMLoc E) {
13283a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    ARMOperand *Op = new ARMOperand(Memory);
1329762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.BaseRegNum = BaseRegNum;
13307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetImm = OffsetImm;
13317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.OffsetRegNum = OffsetRegNum;
1332762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->Mem.ShiftType = ShiftType;
13330d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Op->Mem.ShiftImm = ShiftImm;
13347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->Mem.isNegative = isNegative;
13357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->StartLoc = S;
13367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->EndLoc = E;
13377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Op;
13387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
133916c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
1340f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  static ARMOperand *CreatePostIdxReg(unsigned RegNum, bool isAdd,
1341f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      ARM_AM::ShiftOpc ShiftTy,
1342f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                      unsigned ShiftImm,
13437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                      SMLoc S, SMLoc E) {
13447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    ARMOperand *Op = new ARMOperand(PostIndexRegister);
13457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Op->PostIdxReg.RegNum = RegNum;
1346f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.isAdd = isAdd;
1347f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftTy = ShiftTy;
1348f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Op->PostIdxReg.ShiftImm = ShiftImm;
1349762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->StartLoc = S;
1350762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    Op->EndLoc = E;
13513a69756e392942bc522193f38d7f33958ed3b131Chris Lattner    return Op;
1352a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
1353706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1354706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) {
1355706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MemBarrierOpt);
1356706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->MBOpt.Val = Opt;
1357706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->StartLoc = S;
1358706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    Op->EndLoc = S;
1359706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    return Op;
1360706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  }
1361a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1362a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  static ARMOperand *CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) {
1363a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(ProcIFlags);
1364a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->IFlags.Val = IFlags;
1365a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->StartLoc = S;
1366a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Op->EndLoc = S;
1367a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    return Op;
1368a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1369584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1370584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  static ARMOperand *CreateMSRMask(unsigned MMask, SMLoc S) {
1371584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    ARMOperand *Op = new ARMOperand(MSRMask);
1372584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->MMask.Val = MMask;
1373584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->StartLoc = S;
1374584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Op->EndLoc = S;
1375584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return Op;
1376584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  }
1377a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby};
1378a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1379a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby} // end anonymous namespace.
1380a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1381b7f689bab98777236a2bf600f299d232d246bb61Jim Grosbachvoid ARMOperand::print(raw_ostream &OS) const {
1382fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  switch (Kind) {
1383fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case CondCode:
13846a5c22ed89c8bb73034a70105340acf6539dc58bDaniel Dunbar    OS << "<ARMCC::" << ARMCondCodeToString(getCondCode()) << ">";
1385fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1386d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach  case CCOut:
1387d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    OS << "<ccout " << getReg() << ">";
1388d67641b6f804110505a69aaed5479f446bbbb34eJim Grosbach    break;
138989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ITCondMask: {
139089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    static char MaskStr[][6] = { "()", "(t)", "(e)", "(tt)", "(et)", "(te)",
139189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(ee)", "(ttt)", "(ett)", "(tet)", "(eet)", "(tte)", "(ete)",
139289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      "(tee)", "(eee)" };
139389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    assert((ITMask.Mask & 0xf) == ITMask.Mask);
139489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    OS << "<it-mask " << MaskStr[ITMask.Mask] << ">";
139589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
139689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
1397fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocNum:
1398fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor number: " << getCoproc() << ">";
1399fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1400fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  case CoprocReg:
1401fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    OS << "<coprocessor register: " << getCoproc() << ">";
1402fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    break;
1403584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  case MSRMask:
1404584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    OS << "<mask: " << getMSRMask() << ">";
1405584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    break;
1406fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Immediate:
1407fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    getImm()->print(OS);
1408fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1409706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  case MemBarrierOpt:
1410706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    OS << "<ARM_MB::" << MemBOptToString(getMemBarrierOpt()) << ">";
1411706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    break;
1412fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Memory:
14136ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << "<memory "
14147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach       << " base:" << Mem.BaseRegNum;
14156ec56204f372df73e4a27085b188a72548b867acDaniel Dunbar    OS << ">";
1416fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
14177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  case PostIndexRegister:
1418f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << "post-idx register " << (PostIdxReg.isAdd ? "" : "-")
1419f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach       << PostIdxReg.RegNum;
1420f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    if (PostIdxReg.ShiftTy != ARM_AM::no_shift)
1421f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach      OS << ARM_AM::getShiftOpcStr(PostIdxReg.ShiftTy) << " "
1422f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach         << PostIdxReg.ShiftImm;
1423f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    OS << ">";
14247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    break;
1425a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  case ProcIFlags: {
1426a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << "<ARM_PROC::";
1427a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IFlags = getProcIFlags();
1428a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    for (int i=2; i >= 0; --i)
1429a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      if (IFlags & (1 << i))
1430a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes        OS << ARM_PROC::IFlagsToString(1 << i);
1431a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    OS << ">";
1432a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    break;
1433a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1434fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Register:
143550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    OS << "<register " << getReg() << ">";
1436fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1437580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  case ShifterImmediate:
1438580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    OS << "<shift " << (ShifterImm.isASR ? "asr" : "lsl")
1439580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach       << " #" << ShifterImm.Imm << ">";
1440e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    break;
1441e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  case ShiftedRegister:
144292a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_reg "
1443af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedReg.SrcReg
1444af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedReg.ShiftImm))
1445af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << RegShiftedReg.ShiftReg << ", "
1446af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getSORegOffset(RegShiftedReg.ShiftImm)
1447e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach       << ">";
14480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    break;
144992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  case ShiftedImmediate:
145092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    OS << "<so_reg_imm "
1451af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << RegShiftedImm.SrcReg
1452af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(RegShiftedImm.ShiftImm))
1453af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach       << ", " << ARM_AM::getSORegOffset(RegShiftedImm.ShiftImm)
145492a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson       << ">";
145592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    break;
14567e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  case RotateImmediate:
14577e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    OS << "<ror " << " #" << (RotImm.Imm * 8) << ">";
14587e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    break;
1459293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  case BitfieldDescriptor:
1460293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    OS << "<bitfield " << "lsb: " << Bitfield.LSB
1461293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach       << ", width: " << Bitfield.Width << ">";
1462293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    break;
14630f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case RegisterList:
14640f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case DPRRegisterList:
14650f6307561359fac4425a0b9e512931cf96c1ec5bBill Wendling  case SPRRegisterList: {
14668d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << "<register_list ";
14678d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
14685fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    const SmallVectorImpl<unsigned> &RegList = getRegList();
14695fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling    for (SmallVectorImpl<unsigned>::const_iterator
14707729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           I = RegList.begin(), E = RegList.end(); I != E; ) {
14717729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      OS << *I;
14727729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling      if (++I < E) OS << ", ";
14738d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    }
14748d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling
14758d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    OS << ">";
14768d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling    break;
14778d5acb7007decaf0c30bf4a3d4c55e5cc2cce0a7Bill Wendling  }
1478fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  case Token:
1479fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    OS << "'" << getToken() << "'";
1480fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar    break;
1481fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar  }
1482fa315de8f44ddb318a7c6ff913e80d71d7c68859Daniel Dunbar}
14833483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14843483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// @name Auto-generated Match Functions
14853483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// {
14863483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14873483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbarstatic unsigned MatchRegisterName(StringRef Name);
14883483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
14893483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar/// }
14903483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
149169df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilsonbool ARMAsmParser::ParseRegister(unsigned &RegNo,
149269df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson                                 SMLoc &StartLoc, SMLoc &EndLoc) {
14931355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  RegNo = tryParseRegister();
1494bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
1495bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky  return (RegNo == (unsigned)-1);
1496bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky}
1497bf7553210ae44f05e7460edeae1ee499d8a22dcbRoman Divacky
14989c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Try to parse a register name.  The token must be an Identifier when called,
1499e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// and if it is a register name the token is eaten and the register number is
1500e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// returned.  Otherwise return -1.
15013a69756e392942bc522193f38d7f33958ed3b131Chris Lattner///
15021355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachint ARMAsmParser::tryParseRegister() {
150318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
15047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) return -1;
1505d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
1506a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // FIXME: Validate register for the current architecture; we have to do
1507a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  // validation later, so maybe there is no need for this here.
15080c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string upperCase = Tok.getString().str();
15090c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
15100c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  unsigned RegNum = MatchRegisterName(lowerCase);
15110c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) {
15120c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson    RegNum = StringSwitch<unsigned>(lowerCase)
15130c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r13", ARM::SP)
15140c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r14", ARM::LR)
15150c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("r15", ARM::PC)
15160c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Case("ip", ARM::R12)
15170c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson      .Default(0);
15180c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  }
15190c9f250d54ed59108fffe5ce2f7df7bc8448915cOwen Anderson  if (!RegNum) return -1;
152069df72367f45c0414541196efaf7c13b1ccd3f08Bob Wilson
1521b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat identifier token.
1522e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  return RegNum;
1523e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner}
1524d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
152519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// Try to parse a shifter  (e.g., "lsl <amt>"). On success, return 0.
152619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// If a recoverable error occurs, return 1. If an irrecoverable error
152719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// occurs, return -1. An irrecoverable error is one where tokens have been
152819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// consumed in the process of trying to parse the shifter (i.e., when it is
152919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach// indeed a shifter operand, but malformed).
15300d87ec21d79c8622733b8367aa41067169602480Jim Grosbachint ARMAsmParser::tryParseShiftRegister(
15310082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
15320082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
15330082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  const AsmToken &Tok = Parser.getTok();
15340082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
15350082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
15360082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string upperCase = Tok.getString().str();
15370082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  std::string lowerCase = LowercaseString(upperCase);
15380082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase)
15390082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsl", ARM_AM::lsl)
15400082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("lsr", ARM_AM::lsr)
15410082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("asr", ARM_AM::asr)
15420082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("ror", ARM_AM::ror)
15430082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Case("rrx", ARM_AM::rrx)
15440082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      .Default(ARM_AM::no_shift);
15450082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
15460082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson  if (ShiftTy == ARM_AM::no_shift)
154719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    return 1;
15480082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
1549e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  Parser.Lex(); // Eat the operator.
1550e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
1551e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // The source register for the shift has already been added to the
1552e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // operand list, so we need to pop it off and combine it into the shifted
1553e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  // register operand instead.
1554eac0796542d098caa371856d545faa6cdab5aad3Benjamin Kramer  OwningPtr<ARMOperand> PrevOp((ARMOperand*)Operands.pop_back_val());
1555e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (!PrevOp->isReg())
1556e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    return Error(PrevOp->getStartLoc(), "shift must be of a register");
1557e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int SrcReg = PrevOp->getReg();
1558e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int64_t Imm = 0;
1559e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  int ShiftReg = 0;
1560e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  if (ShiftTy == ARM_AM::rrx) {
1561e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // RRX Doesn't have an explicit shift amount. The encoder expects
1562e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // the shift register to be the same as the source register. Seems odd,
1563e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // but OK.
1564e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    ShiftReg = SrcReg;
1565e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  } else {
1566e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    // Figure out if this is shifted by a constant or a register (for non-RRX).
1567e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    if (Parser.getTok().is(AsmToken::Hash)) {
1568e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Parser.Lex(); // Eat hash.
1569e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc ImmLoc = Parser.getTok().getLoc();
1570e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCExpr *ShiftExpr = 0;
157119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (getParser().ParseExpression(ShiftExpr)) {
157219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
157319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
157419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1575e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // The expression must be evaluatable as an immediate.
1576e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftExpr);
157719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (!CE) {
157819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "invalid immediate shift value");
157919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
158019906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
1581e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // Range check the immediate.
1582e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsl, ror: 0 <= imm <= 31
1583e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      // lsr, asr: 0 <= imm <= 32
1584e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      Imm = CE->getValue();
1585e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      if (Imm < 0 ||
1586e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsl || ShiftTy == ARM_AM::ror) && Imm > 31) ||
1587e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach          ((ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr) && Imm > 32)) {
158819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error(ImmLoc, "immediate shift value out of range");
158919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
1590e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      }
1591e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach    } else if (Parser.getTok().is(AsmToken::Identifier)) {
15921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      ShiftReg = tryParseRegister();
1593e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach      SMLoc L = Parser.getTok().getLoc();
159419906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      if (ShiftReg == -1) {
159519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        Error (L, "expected immediate or register in shift operand");
159619906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach        return -1;
159719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      }
159819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    } else {
159919906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      Error (Parser.getTok().getLoc(),
1600e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach                    "expected immediate or register in shift operand");
160119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return -1;
160219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    }
1603e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach  }
1604e8606dc7c878d4562da5e3e5609b9d7d734d498cJim Grosbach
160592a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  if (ShiftReg && ShiftTy != ARM_AM::rrx)
160692a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
1607af6981f2f59f0d825ad973e0bed8fff5d302196fJim Grosbach                                                         ShiftReg, Imm,
16080082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson                                               S, Parser.getTok().getLoc()));
160992a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson  else
161092a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson    Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
161192a202213bb4c20301abf6ab64e46df3695e60bfOwen Anderson                                               S, Parser.getTok().getLoc()));
16120082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
161319906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  return 0;
16140082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson}
16150082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
16160082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson
161750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// Try to parse a register name.  The token must be an Identifier when called.
161850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// If it's a register, an AsmOperand is created. Another AsmOperand is created
161950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling/// if there is a "writeback". 'true' if it's not a register.
1620e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner///
1621e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// TODO this is likely to change to allow different register types and or to
1622e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner/// parse for a specific register type.
162350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
16241355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachtryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1625e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  SMLoc S = Parser.getTok().getLoc();
16261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int RegNo = tryParseRegister();
1627e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  if (RegNo == -1)
162850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1629d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
163050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1631a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1632e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  const AsmToken &ExclaimTok = Parser.getTok();
1633e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner  if (ExclaimTok.is(AsmToken::Exclaim)) {
163450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateToken(ExclaimTok.getString(),
163550d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling                                               ExclaimTok.getLoc()));
1636e5658fa15ebb733e0786a96c1852c7cf590d5b24Chris Lattner    Parser.Lex(); // Eat exclaim token
163799e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby  }
163899e6d4e8392497d950d48b03f45c79b7dd131327Kevin Enderby
163950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1640a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
1641a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
1642fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// MatchCoprocessorOperandName - Try to parse an coprocessor related
1643fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
1644fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// "c5", ...
1645fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopesstatic int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
1646e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // Use the same layout as the tablegen'erated register name matcher. Ugly,
1647e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  // but efficient.
1648e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  switch (Name.size()) {
1649e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  default: break;
1650e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 2:
1651fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp)
1652e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1653e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[1]) {
1654e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1655e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 0;
1656e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 1;
1657e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 2;
1658e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 3;
1659e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 4;
1660e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 5;
1661e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '6': return 6;
1662e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '7': return 7;
1663e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '8': return 8;
1664e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '9': return 9;
1665e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1666e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1667e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  case 3:
1668fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    if (Name[0] != CoprocOp || Name[1] != '1')
1669e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson      return -1;
1670e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    switch (Name[2]) {
1671e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    default:  return -1;
1672e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '0': return 10;
1673e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '1': return 11;
1674e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '2': return 12;
1675e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '3': return 13;
1676e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '4': return 14;
1677e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    case '5': return 15;
1678e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    }
1679e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    break;
1680e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  }
1681e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1682e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  return -1;
1683e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1684e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
168589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach/// parseITCondCode - Try to parse a condition code for an IT instruction.
168689df996ab20609676ecc8823f58414d598b09b46Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
168789df996ab20609676ecc8823f58414d598b09b46Jim GrosbachparseITCondCode(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
168889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
168989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  const AsmToken &Tok = Parser.getTok();
169089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (!Tok.is(AsmToken::Identifier))
169189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
169289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  unsigned CC = StringSwitch<unsigned>(Tok.getString())
169389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("eq", ARMCC::EQ)
169489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ne", ARMCC::NE)
169589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hs", ARMCC::HS)
169689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cs", ARMCC::HS)
169789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lo", ARMCC::LO)
169889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("cc", ARMCC::LO)
169989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("mi", ARMCC::MI)
170089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("pl", ARMCC::PL)
170189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vs", ARMCC::VS)
170289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("vc", ARMCC::VC)
170389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("hi", ARMCC::HI)
170489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ls", ARMCC::LS)
170589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("ge", ARMCC::GE)
170689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("lt", ARMCC::LT)
170789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("gt", ARMCC::GT)
170889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("le", ARMCC::LE)
170989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Case("al", ARMCC::AL)
171089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    .Default(~0U);
171189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (CC == ~0U)
171289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    return MatchOperand_NoMatch;
171389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Parser.Lex(); // Eat the token.
171489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
171589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  Operands.push_back(ARMOperand::CreateCondCode(ARMCC::CondCodes(CC), S));
171689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
171789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  return MatchOperand_Success;
171889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach}
171989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
172043904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocNumOperand - Try to parse an coprocessor number operand. The
1721fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1722fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1723f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
172443904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1725e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  SMLoc S = Parser.getTok().getLoc();
1726e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  const AsmToken &Tok = Parser.getTok();
1727e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1728e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1729fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
1730e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  if (Num == -1)
1731f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1732e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1733e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson  Parser.Lex(); // Eat identifier token.
1734fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
1735f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1736fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes}
1737fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
173843904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseCoprocRegOperand - Try to parse an coprocessor register operand. The
1739fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// token must be an Identifier when called, and if it is a coprocessor
1740fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes/// number, the token is eaten and the operand is added to the operand list.
1741f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
174243904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1743fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1744fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1745fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1746fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1747fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
1748fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  if (Reg == -1)
1749f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1750fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
1751fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1752fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
1753f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1754e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson}
1755e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
1756c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// Parse a register list, return it if successful else return null.  The first
1757c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner/// token must be a '{' when called.
175850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
17591355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachparseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
176018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LCurly) &&
1761a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Curly Brace");
1762e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc S = Parser.getTok().getLoc();
176316c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
17647729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  // Read the rest of the registers in the list.
17657729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  unsigned PrevRegNum = 0;
17665fa22a19750c082ff161db1702ebe96dd2a787e7Bill Wendling  SmallVector<std::pair<unsigned, SMLoc>, 32> Registers;
1767d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
17687729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  do {
1769e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    bool IsRange = Parser.getTok().is(AsmToken::Minus);
17707729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling    Parser.Lex(); // Eat non-identifier token.
1771d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
177218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    const AsmToken &RegTok = Parser.getTok();
1773d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby    SMLoc RegLoc = RegTok.getLoc();
1774c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegTok.isNot(AsmToken::Identifier)) {
1775c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
177650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1777c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1778e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
17791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    int RegNum = tryParseRegister();
1780c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    if (RegNum == -1) {
1781c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner      Error(RegLoc, "register expected");
178250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1783c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    }
1784d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1785e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    if (IsRange) {
1786e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      int Reg = PrevRegNum;
1787e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      do {
1788e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        ++Reg;
1789e717610f53e0465cde198536561a3c00ce29d59fBill Wendling        Registers.push_back(std::make_pair(Reg, RegLoc));
1790e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      } while (Reg != RegNum);
1791e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    } else {
1792e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Registers.push_back(std::make_pair(RegNum, RegLoc));
1793e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1794e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1795e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    PrevRegNum = RegNum;
17967729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling  } while (Parser.getTok().is(AsmToken::Comma) ||
17977729e06c128be01fc564870d5ea3d22d236dddb5Bill Wendling           Parser.getTok().is(AsmToken::Minus));
1798e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
1799e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Process the right curly brace of the list.
180018b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &RCurlyTok = Parser.getTok();
1801c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  if (RCurlyTok.isNot(AsmToken::RCurly)) {
1802c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner    Error(RCurlyTok.getLoc(), "'}' expected");
180350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
1804c0ddfaa134fe60c09686906b3a8f489531653453Chris Lattner  }
1805d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
1806e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  SMLoc E = RCurlyTok.getLoc();
1807e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  Parser.Lex(); // Eat right curly brace token.
180803f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
1809e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  // Verify the register list.
18108e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling  bool EmittedWarning = false;
181111e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach  unsigned HighRegNum = 0;
181211e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach  BitVector RegMap(32);
181311e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
181411e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach    const std::pair<unsigned, SMLoc> &RegInfo = Registers[i];
18157caebff83d90a59aa74876ff887e822387f479e0Bill Wendling    unsigned Reg = getARMRegisterNumbering(RegInfo.first);
1816e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
18178e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (RegMap[Reg]) {
1818e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Error(RegInfo.second, "register duplicated in register list");
181950d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
1820e717610f53e0465cde198536561a3c00ce29d59fBill Wendling    }
1821e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
18228e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    if (!EmittedWarning && Reg < HighRegNum)
1823e717610f53e0465cde198536561a3c00ce29d59fBill Wendling      Warning(RegInfo.second,
1824e717610f53e0465cde198536561a3c00ce29d59fBill Wendling              "register not in ascending order in register list");
1825e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
182611e03e7c2d0c163e54b911ad1e665616dc0bcc8cJim Grosbach    RegMap.set(Reg);
18278e8b18bcfa87ff919f127b1270a6891db1c9021fBill Wendling    HighRegNum = std::max(Reg, HighRegNum);
1828e717610f53e0465cde198536561a3c00ce29d59fBill Wendling  }
1829e717610f53e0465cde198536561a3c00ce29d59fBill Wendling
183050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  Operands.push_back(ARMOperand::CreateRegList(Registers, S, E));
183150d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  return false;
1832d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby}
1833d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby
183443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
1835f922c47143d247cbae14b294a0bada139bcd35f6Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
183643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1837706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1838706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1839706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1840706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  StringRef OptStr = Tok.getString();
1841706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1842706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  unsigned Opt = StringSwitch<unsigned>(OptStr.slice(0, OptStr.size()))
1843706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("sy",    ARM_MB::SY)
1844706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("st",    ARM_MB::ST)
1845032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("sh",    ARM_MB::ISH)
1846706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ish",   ARM_MB::ISH)
1847032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("shst",  ARM_MB::ISHST)
1848706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("ishst", ARM_MB::ISHST)
1849706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nsh",   ARM_MB::NSH)
1850032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("un",    ARM_MB::NSH)
1851706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("nshst", ARM_MB::NSHST)
1852032434d622b6cd030a60bb9045a520c93b0d7d68Jim Grosbach    .Case("unst",  ARM_MB::NSHST)
1853706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("osh",   ARM_MB::OSH)
1854706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Case("oshst", ARM_MB::OSHST)
1855706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes    .Default(~0U);
1856706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1857706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  if (Opt == ~0U)
1858f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return MatchOperand_NoMatch;
1859706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
1860706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1861706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S));
1862f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  return MatchOperand_Success;
1863706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes}
1864706d946cfe44fa93f482c3a56ed42d52ca81b257Bruno Cardoso Lopes
186543904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseProcIFlagsOperand - Try to parse iflags from CPS instruction.
1866a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
186743904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseProcIFlagsOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1868a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1869a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1870a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1871a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  StringRef IFlagsStr = Tok.getString();
1872a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1873a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned IFlags = 0;
1874a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  for (int i = 0, e = IFlagsStr.size(); i != e; ++i) {
1875a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned Flag = StringSwitch<unsigned>(IFlagsStr.substr(i, 1))
1876a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("a", ARM_PROC::A)
1877a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("i", ARM_PROC::I)
1878a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Case("f", ARM_PROC::F)
1879a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    .Default(~0U);
1880a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1881a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // If some specific iflag is already set, it means that some letter is
1882a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // present more than once, this is not acceptable.
1883a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (Flag == ~0U || (IFlags & Flag))
1884a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      return MatchOperand_NoMatch;
1885a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1886a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    IFlags |= Flag;
1887a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
1888a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1889a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1890a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateProcIFlags((ARM_PROC::IFlags)IFlags, S));
1891a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  return MatchOperand_Success;
1892584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes}
1893584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
189443904299b05bdf579415749041f77c4490fe5f5bJim Grosbach/// parseMSRMaskOperand - Try to parse mask flags from MSR instruction.
1895584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso LopesARMAsmParser::OperandMatchResultTy ARMAsmParser::
189643904299b05bdf579415749041f77c4490fe5f5bJim GrosbachparseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1897584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  SMLoc S = Parser.getTok().getLoc();
1898584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  const AsmToken &Tok = Parser.getTok();
1899584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
1900584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Mask = Tok.getString();
1901584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1902584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
1903584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  size_t Start = 0, Next = Mask.find('_');
1904584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  StringRef Flags = "";
1905b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach  std::string SpecReg = LowercaseString(Mask.slice(Start, Next));
1906584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (Next != StringRef::npos)
1907584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    Flags = Mask.slice(Next+1, Mask.size());
1908584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1909584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // FlagsVal contains the complete mask:
1910584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 3-0: Mask
1911584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1912584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  unsigned FlagsVal = 0;
1913584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1914584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "apsr") {
1915584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = StringSwitch<unsigned>(Flags)
1916b29b4dd988c50d5c4a15cd196e7910bf46f30b83Jim Grosbach    .Case("nzcvq",  0x8) // same as CPSR_f
1917584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("g",      0x4) // same as CPSR_s
1918584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Case("nzcvqg", 0xc) // same as CPSR_fs
1919584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    .Default(~0U);
1920584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
19214b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    if (FlagsVal == ~0U) {
1922584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (!Flags.empty())
1923584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1924584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      else
1925584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        FlagsVal = 0; // No flag
19264b19c9865ee94367d7b3594c36e59e4c15ba82ccJoerg Sonnenberger    }
1927584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else if (SpecReg == "cpsr" || SpecReg == "spsr") {
192856926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes    if (Flags == "all") // cpsr_all is an alias for cpsr_fc
192956926a39619bd644c83c4128f0b55189e52707d7Bruno Cardoso Lopes      Flags = "fc";
1930584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    for (int i = 0, e = Flags.size(); i != e; ++i) {
1931584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      unsigned Flag = StringSwitch<unsigned>(Flags.substr(i, 1))
1932584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("c", 1)
1933584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("x", 2)
1934584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("s", 4)
1935584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Case("f", 8)
1936584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      .Default(~0U);
1937584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1938584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // If some specific flag is already set, it means that some letter is
1939584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      // present more than once, this is not acceptable.
1940584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      if (FlagsVal == ~0U || (FlagsVal & Flag))
1941584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes        return MatchOperand_NoMatch;
1942584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes      FlagsVal |= Flag;
1943584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    }
1944584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  } else // No match for special register.
1945584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    return MatchOperand_NoMatch;
1946584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1947584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Special register without flags are equivalent to "fc" flags.
1948584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (!FlagsVal)
1949584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal = 0x9;
1950584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1951584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  // Bit 4: Special Reg (cpsr, apsr => 0; spsr => 1)
1952584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  if (SpecReg == "spsr")
1953584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes    FlagsVal |= 16;
1954584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes
1955584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Parser.Lex(); // Eat identifier token.
1956584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
1957584bf7bb03e4cf1475b26851edcc1ddb66b85028Bruno Cardoso Lopes  return MatchOperand_Success;
1958a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes}
1959a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
1960f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
1961f6c0525d421cb48119423a96e23289b473eddbd7Jim GrosbachparsePKHImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands, StringRef Op,
1962f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach            int Low, int High) {
1963f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const AsmToken &Tok = Parser.getTok();
1964f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
1965f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1966f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1967f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1968f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  StringRef ShiftName = Tok.getString();
1969f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string LowerOp = LowercaseString(Op);
1970f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  std::string UpperOp = UppercaseString(Op);
1971f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (ShiftName != LowerOp && ShiftName != UpperOp) {
1972f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), Op + " operand expected.");
1973f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1974f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1975f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat shift type token.
1976f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1977f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  // There must be a '#' and a shift amount.
1978f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
1979f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
1980f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1981f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1982f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Parser.Lex(); // Eat hash token.
1983f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
1984f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCExpr *ShiftAmount;
1985f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
1986f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
1987f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "illegal expression");
1988f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1989f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1990f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
1991f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (!CE) {
1992f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "constant expression expected");
1993f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1994f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
1995f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  int Val = CE->getValue();
1996f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  if (Val < Low || Val > High) {
1997f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    Error(Loc, "immediate value out of range");
1998f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach    return MatchOperand_ParseFail;
1999f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  }
2000f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2001f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(CE, Loc, Parser.getTok().getLoc()));
2002f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2003f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach  return MatchOperand_Success;
2004f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach}
2005f6c0525d421cb48119423a96e23289b473eddbd7Jim Grosbach
2006c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2007c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim GrosbachparseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2008c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  const AsmToken &Tok = Parser.getTok();
2009c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  SMLoc S = Tok.getLoc();
2010c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2011c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2012c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2013c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2014c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  int Val = StringSwitch<int>(Tok.getString())
2015c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("be", 1)
2016c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Case("le", 0)
2017c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    .Default(-1);
2018c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Parser.Lex(); // Eat the token.
2019c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2020c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (Val == -1) {
2021c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Error(Tok.getLoc(), "'be' or 'le' operand expected");
2022c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return MatchOperand_ParseFail;
2023c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
2024c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
2025c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                                                  getContext()),
2026c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                                           S, Parser.getTok().getLoc()));
2027c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  return MatchOperand_Success;
2028c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach}
2029c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach
2030580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// parseShifterImm - Parse the shifter immediate operand for SSAT/USAT
2031580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach/// instructions. Legal values are:
2032580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     lsl #n  'n' in [0,31]
2033580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///     asr #n  'n' in [1,32]
2034580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach///             n == 32 encoded as n == 0.
2035580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2036580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim GrosbachparseShifterImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2037580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const AsmToken &Tok = Parser.getTok();
2038580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc S = Tok.getLoc();
2039580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
2040580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2041580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2042580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2043580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  StringRef ShiftName = Tok.getString();
2044580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  bool isASR;
2045580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (ShiftName == "lsl" || ShiftName == "LSL")
2046580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = false;
2047580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else if (ShiftName == "asr" || ShiftName == "ASR")
2048580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    isASR = true;
2049580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  else {
2050580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(S, "shift operator 'asr' or 'lsl' expected");
2051580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2052580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2053580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat the operator.
2054580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2055580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  // A '#' and a shift amount.
2056580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2057580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2058580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2059580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2060580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Parser.Lex(); // Eat hash token.
2061580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2062580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCExpr *ShiftAmount;
2063580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  SMLoc E = Parser.getTok().getLoc();
2064580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
2065580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "malformed shift expression");
2066580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2067580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2068580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
2069580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (!CE) {
2070580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    Error(E, "shift amount must be an immediate");
2071580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    return MatchOperand_ParseFail;
2072580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2073580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2074580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  int64_t Val = CE->getValue();
2075580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  if (isASR) {
2076580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2077580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 1 || Val > 32) {
2078580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'asr' shift amount must be in range [1,32]");
2079580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2080580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
2081580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // asr #32 encoded as asr #0.
2082580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val == 32) Val = 0;
2083580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  } else {
2084580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    // Shift amount must be in [1,32]
2085580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    if (Val < 0 || Val > 31) {
2086580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      Error(E, "'lsr' shift amount must be in range [0,31]");
2087580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach      return MatchOperand_ParseFail;
2088580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach    }
2089580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  }
2090580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2091580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  E = Parser.getTok().getLoc();
2092580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  Operands.push_back(ARMOperand::CreateShifterImm(isASR, Val, S, E));
2093580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
2094580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach  return MatchOperand_Success;
2095580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach}
2096580f4a9c1c2fcbb8877463f873c6e9ca2a5ccf9fJim Grosbach
20977e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// parseRotImm - Parse the shifter immediate operand for SXTB/UXTB family
20987e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach/// of instructions. Legal values are:
20997e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach///     ror #n  'n' in {0, 8, 16, 24}
21007e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
21017e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim GrosbachparseRotImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
21027e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const AsmToken &Tok = Parser.getTok();
21037e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc S = Tok.getLoc();
21047e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Tok.isNot(AsmToken::Identifier)) {
21057e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(S, "rotate operator 'ror' expected");
21067e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
21077e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21087e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  StringRef ShiftName = Tok.getString();
21097e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (ShiftName != "ror" && ShiftName != "ROR") {
21107e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(S, "rotate operator 'ror' expected");
21117e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
21127e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21137e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat the operator.
21147e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
21157e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // A '#' and a rotate amount.
21167e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
21177e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
21187e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
21197e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21207e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Parser.Lex(); // Eat hash token.
21217e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
21227e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCExpr *ShiftAmount;
21237e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
21247e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (getParser().ParseExpression(ShiftAmount)) {
21257e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "malformed rotate expression");
21267e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
21277e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21287e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ShiftAmount);
21297e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (!CE) {
21307e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "rotate amount must be an immediate");
21317e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
21327e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21337e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
21347e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  int64_t Val = CE->getValue();
21357e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // Shift amount must be in {0, 8, 16, 24} (0 is undocumented extension)
21367e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // normally, zero is represented in asm by omitting the rotate operand
21377e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  // entirely.
21387e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  if (Val != 8 && Val != 16 && Val != 24 && Val != 0) {
21397e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    Error(E, "'ror' rotate amount must be 8, 16, or 24");
21407e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach    return MatchOperand_ParseFail;
21417e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  }
21427e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
21437e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  E = Parser.getTok().getLoc();
21447e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  Operands.push_back(ARMOperand::CreateRotImm(Val, S, E));
21457e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
21467e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach  return MatchOperand_Success;
21477e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach}
21487e1547ebf726a40e7ed3dbe89a77e1b946a8e2d0Jim Grosbach
2149293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2150293a2ee3063953bb6f5bc828831f985f054782a3Jim GrosbachparseBitfield(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2151293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc S = Parser.getTok().getLoc();
2152293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The bitfield descriptor is really two operands, the LSB and the width.
2153293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2154293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2155293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2156293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2157293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2158293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2159293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *LSBExpr;
2160293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2161293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(LSBExpr)) {
2162293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2163293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2164293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2165293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(LSBExpr);
2166293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2167293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be an immediate");
2168293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2169293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2170293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2171293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t LSB = CE->getValue();
2172293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [0,31]
2173293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (LSB < 0 || LSB > 31) {
2174293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'lsb' operand must be in the range [0,31]");
2175293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2176293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2177293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2178293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2179293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // Expect another immediate operand.
2180293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Comma)) {
2181293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "too few operands");
2182293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2183293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2184293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2185293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Parser.getTok().isNot(AsmToken::Hash)) {
2186293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(Parser.getTok().getLoc(), "'#' expected");
2187293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2188293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2189293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Parser.Lex(); // Eat hash token.
2190293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2191293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  const MCExpr *WidthExpr;
2192293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (getParser().ParseExpression(WidthExpr)) {
2193293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "malformed immediate expression");
2194293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2195293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2196293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  CE = dyn_cast<MCConstantExpr>(WidthExpr);
2197293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (!CE) {
2198293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be an immediate");
2199293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2200293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2201293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2202293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  int64_t Width = CE->getValue();
2203293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  // The LSB must be in the range [1,32-lsb]
2204293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  if (Width < 1 || Width > 32 - LSB) {
2205293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    Error(E, "'width' operand must be in the range [1,32-lsb]");
2206293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach    return MatchOperand_ParseFail;
2207293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  }
2208293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  E = Parser.getTok().getLoc();
2209293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2210293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  Operands.push_back(ARMOperand::CreateBitfield(LSB, Width, S, E));
2211293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
2212293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach  return MatchOperand_Success;
2213293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach}
2214293a2ee3063953bb6f5bc828831f985f054782a3Jim Grosbach
22157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
22167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
22177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2218f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // postidx_reg := '+' register {, shift}
2219f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | '-' register {, shift}
2220f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  //              | register {, shift}
22217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
22227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
22237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // in the case where there is no match, as other alternatives take other
22247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // parse methods.
22257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  AsmToken Tok = Parser.getTok();
22267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc S = Tok.getLoc();
22277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool haveEaten = false;
222816578b50889329eb62774148091ba0f38b681a09Jim Grosbach  bool isAdd = true;
22297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int Reg = -1;
22307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
22317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+' token.
22327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
22337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
22347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-' token.
223516578b50889329eb62774148091ba0f38b681a09Jim Grosbach    isAdd = false;
22367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    haveEaten = true;
22377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
22387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
22397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Reg = tryParseRegister();
22407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Reg == -1) {
22417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!haveEaten)
22427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return MatchOperand_NoMatch;
22437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
22447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return MatchOperand_ParseFail;
22457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
22467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
22477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2248f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  ARM_AM::ShiftOpc ShiftTy = ARM_AM::no_shift;
2249f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  unsigned ShiftImm = 0;
22500d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
22510d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    Parser.Lex(); // Eat the ','.
22520d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftTy, ShiftImm))
22530d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach      return MatchOperand_ParseFail;
22540d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  }
2255f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach
2256f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ShiftTy,
2257f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach                                                  ShiftImm, S, E));
22587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
22597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return MatchOperand_Success;
22607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
22617ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2262251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachARMAsmParser::OperandMatchResultTy ARMAsmParser::
2263251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim GrosbachparseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2264251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Check for a post-index addressing register operand. Specifically:
2265251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // am3offset := '+' register
2266251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | '-' register
2267251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | register
2268251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # imm
2269251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # + imm
2270251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  //              | # - imm
2271251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2272251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // This method must return MatchOperand_NoMatch without consuming any tokens
2273251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // in the case where there is no match, as other alternatives take other
2274251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // parse methods.
2275251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  AsmToken Tok = Parser.getTok();
2276251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc S = Tok.getLoc();
2277251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2278251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  // Do immediates first, as we always parse those if we have a '#'.
2279251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
2280251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '#'.
2281251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Explicitly look for a '-', as we need to encode negative zero
2282251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // differently.
2283251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2284251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCExpr *Offset;
2285251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (getParser().ParseExpression(Offset))
2286251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2287251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
2288251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!CE) {
2289251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Error(S, "constant expression expected");
2290251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_ParseFail;
2291251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    }
2292251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    SMLoc E = Tok.getLoc();
2293251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    // Negative zero is encoded as the flag value INT32_MIN.
2294251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    int32_t Val = CE->getValue();
2295251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (isNegative && Val == 0)
2296251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      Val = INT32_MIN;
2297251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2298251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Operands.push_back(
2299251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      ARMOperand::CreateImm(MCConstantExpr::Create(Val, getContext()), S, E));
2300251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2301251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_Success;
2302251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2303251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2304251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2305251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool haveEaten = false;
2306251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  bool isAdd = true;
2307251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  int Reg = -1;
2308251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Tok.is(AsmToken::Plus)) {
2309251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '+' token.
2310251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2311251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  } else if (Tok.is(AsmToken::Minus)) {
2312251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Parser.Lex(); // Eat the '-' token.
2313251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    isAdd = false;
2314251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    haveEaten = true;
2315251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2316251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Parser.getTok().is(AsmToken::Identifier))
2317251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Reg = tryParseRegister();
2318251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  if (Reg == -1) {
2319251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    if (!haveEaten)
2320251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach      return MatchOperand_NoMatch;
2321251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    Error(Parser.getTok().getLoc(), "register expected");
2322251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach    return MatchOperand_ParseFail;
2323251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  }
2324251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  SMLoc E = Parser.getTok().getLoc();
2325251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2326251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  Operands.push_back(ARMOperand::CreatePostIdxReg(Reg, isAdd, ARM_AM::no_shift,
2327251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach                                                  0, S, E));
2328251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
2329251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach  return MatchOperand_Success;
2330251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach}
2331251bf25e7ee9702fed2a66deeb404ce473f7bac1Jim Grosbach
23321355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2333ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2334ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2335ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
23361355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2337ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2338ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2339ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
2340ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2341ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2342ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
23437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2344ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2345ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2346ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2347ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
23489ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// cvtLdWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
23499ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// Needed here because the Asm Gen Matcher can't handle properly tied operands
23509ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson/// when they refer multiple MIOperands inside a single one.
23519ab0f25fc194b4315db1b87d38d4024054120bf6Owen Andersonbool ARMAsmParser::
23529ab0f25fc194b4315db1b87d38d4024054120bf6Owen AndersoncvtLdWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
23539ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23549ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
23559ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
23569ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  // Create a writeback register dummy placeholder.
23579ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
23589ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
23599ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
23609ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
23619ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return true;
23629ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
23639ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
23649ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
2365548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// cvtStWriteBackRegAddrModeImm12 - Convert parsed operands to MCInst.
2366548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2367548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2368548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbachbool ARMAsmParser::
2369548340c4bfa596b602f286dfd3a8782817859d95Jim GrosbachcvtStWriteBackRegAddrModeImm12(MCInst &Inst, unsigned Opcode,
2370548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2371548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  // Create a writeback register dummy placeholder.
2372548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2373548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2374548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addMemImm12OffsetOperands(Inst, 2);
2375548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2376548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  return true;
2377548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach}
2378548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach
23791355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// cvtStWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
2380ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2381ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2382ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopesbool ARMAsmParser::
23831355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachcvtStWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
2384ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2385ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2386ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
2387548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2388548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode2Operands(Inst, 3);
2389548340c4bfa596b602f286dfd3a8782817859d95Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
23907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
23917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
23927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
23937b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// cvtStWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
23947b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
23957b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach/// when they refer multiple MIOperands inside a single one.
23967b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbachbool ARMAsmParser::
23977b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim GrosbachcvtStWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
23987b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
23997b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  // Create a writeback register dummy placeholder.
24007b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
24017b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
24027b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
24037b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
24047b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach  return true;
24057b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach}
24067b8f46cf9e31d730acc25be771462e2a6a1a1dfbJim Grosbach
24077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackImm - Convert parsed operands to MCInst.
24087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
24097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
24107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
24117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
24127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2414ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
24157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
24167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
24177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
24187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
24197ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
24207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
24217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2422ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2423ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes  return true;
2424ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes}
2425ae0855401b8c80f96904b6808b0bc4c89216aecdBruno Cardoso Lopes
24267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtLdExtTWriteBackReg - Convert parsed operands to MCInst.
2427ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2428ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2429ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
24307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtLdExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
24317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2433aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2434ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2435ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
24367ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
24377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
24387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
24397ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
24407ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
24417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
24427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  return true;
24437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach}
2444aa3402e2800e85107a8f803be2942633b1c8c384Owen Anderson
24457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackImm - Convert parsed operands to MCInst.
24467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
24477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// when they refer multiple MIOperands inside a single one.
24487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::
24497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackImm(MCInst &Inst, unsigned Opcode,
24507ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Create a writeback register dummy placeholder.
24527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
24537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
24547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
24557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
24567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
24577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
24587ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxImm8Operands(Inst, 1);
24597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2460ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2461ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2462ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2463ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
24647ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// cvtStExtTWriteBackReg - Convert parsed operands to MCInst.
2465ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2466ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes/// when they refer multiple MIOperands inside a single one.
2467ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopesbool ARMAsmParser::
24687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachcvtStExtTWriteBackReg(MCInst &Inst, unsigned Opcode,
24697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2470ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  // Create a writeback register dummy placeholder.
2471ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  Inst.addOperand(MCOperand::CreateImm(0));
24727ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Rt
2473ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
24747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // addr
24757ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[3])->addMemNoOffsetOperands(Inst, 1);
24767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset
24777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ((ARMOperand*)Operands[4])->addPostIdxRegOperands(Inst, 2);
24787ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // pred
2479ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2480ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes  return true;
2481ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes}
2482ac79e4c82f201c30a06c2cd05baebd20f5b49888Bruno Cardoso Lopes
24832fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// cvtLdrdPre - Convert parsed operands to MCInst.
24842fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
24852fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach/// when they refer multiple MIOperands inside a single one.
24862fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbachbool ARMAsmParser::
24872fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim GrosbachcvtLdrdPre(MCInst &Inst, unsigned Opcode,
24882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
24892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Rt, Rt2
24902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
24912fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
24922fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // Create a writeback register dummy placeholder.
24932fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
24942fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // addr
24952fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
24962fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  // pred
24972fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
24982fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  return true;
24992fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach}
25002fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach
250114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// cvtStrdPre - Convert parsed operands to MCInst.
250214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
250314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach/// when they refer multiple MIOperands inside a single one.
250414605d1a679d55ff25875656e100ff455194ee17Jim Grosbachbool ARMAsmParser::
250514605d1a679d55ff25875656e100ff455194ee17Jim GrosbachcvtStrdPre(MCInst &Inst, unsigned Opcode,
250614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
250714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Create a writeback register dummy placeholder.
250814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
250914605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // Rt, Rt2
251014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
251114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
251214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // addr
251314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
251414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  // pred
251514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
251614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  return true;
251714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach}
251814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach
2519623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
2520623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
2521623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach/// when they refer multiple MIOperands inside a single one.
2522623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbachbool ARMAsmParser::
2523623a454b0f5c300e69a19984d7855a1e976c3d09Jim GrosbachcvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
2524623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach                         const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2525623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
2526623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  // Create a writeback register dummy placeholder.
2527623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(0));
2528623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[3])->addAddrMode3Operands(Inst, 3);
2529623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
2530623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach  return true;
2531623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach}
2532623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
253388ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// cvtThumbMultiple- Convert parsed operands to MCInst.
253488ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// Needed here because the Asm Gen Matcher can't handle properly tied operands
253588ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach/// when they refer multiple MIOperands inside a single one.
253688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbachbool ARMAsmParser::
253788ae2bc6d53bbf58422ff74729da18a53e155b4aJim GrosbachcvtThumbMultiply(MCInst &Inst, unsigned Opcode,
253888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach           const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
253988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // The second source operand must be the same register as the destination
254088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  // operand.
254188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  if (Operands.size() == 6 &&
25427a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
25437a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[5])->getReg()) &&
25447a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach      (((ARMOperand*)Operands[3])->getReg() !=
25457a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach       ((ARMOperand*)Operands[4])->getReg())) {
254688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    Error(Operands[3]->getStartLoc(),
25477a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach          "destination register must match source register");
254888ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return false;
254988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  }
255088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
255188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[1])->addCCOutOperands(Inst, 1);
255288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[4])->addRegOperands(Inst, 1);
25537a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // If we have a three-operand form, use that, else the second source operand
25547a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  // is just the destination operand again.
25557a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  if (Operands.size() == 6)
25567a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    ((ARMOperand*)Operands[5])->addRegOperands(Inst, 1);
25577a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach  else
25587a010694209ce46c4f415c0b42c3bc03dc094a5cJim Grosbach    Inst.addOperand(Inst.getOperand(0));
255988ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  ((ARMOperand*)Operands[2])->addCondCodeOperands(Inst, 2);
256088ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach
256188ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach  return true;
256288ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach}
2563623a454b0f5c300e69a19984d7855a1e976c3d09Jim Grosbach
2564e717610f53e0465cde198536561a3c00ce29d59fBill Wendling/// Parse an ARM memory expression, return false if successful else return true
25659c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// or an error.  The first token must be a '[' when called.
256650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendlingbool ARMAsmParser::
25677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim GrosbachparseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
2568762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
256918b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  assert(Parser.getTok().is(AsmToken::LBrac) &&
2570a60f157b7c6fb60b33598fa5143ed8cb91aa5107Bill Wendling         "Token is not a Left Bracket");
2571762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  S = Parser.getTok().getLoc();
2572b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat left bracket token.
2573a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
257418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &BaseRegTok = Parser.getTok();
25751355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  int BaseRegNum = tryParseRegister();
25767ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (BaseRegNum == -1)
25777ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(BaseRegTok.getLoc(), "register expected");
2578a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
25790571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  // The next token must either be a comma or a closing bracket.
25800571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  const AsmToken &Tok = Parser.getTok();
25810571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar  if (!Tok.is(AsmToken::Comma) && !Tok.is(AsmToken::RBrac))
25827ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Tok.getLoc(), "malformed memory operand");
25830571093f4cf0414724674448fe6b973c0fa705b3Daniel Dunbar
25847ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Tok.is(AsmToken::RBrac)) {
2585762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = Tok.getLoc();
2586b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex(); // Eat right bracket token.
2587a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
25887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, 0, ARM_AM::no_shift,
25897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             0, false, S, E));
259003f44a04e63ff77af12df33e10ffdc473609dfe2Jim Grosbach
25917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
25927ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
259350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
25947ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  assert(Tok.is(AsmToken::Comma) && "Lost comma in memory operand?!");
25957ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat the comma.
259650d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
25977ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If we have a '#' it's an immediate offset, else assume it's a register
25987ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // offset.
25997ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Hash)) {
26007ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '#'.
26017ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
260250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling
26030da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    bool isNegative = getParser().getTok().is(AsmToken::Minus);
26047ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Offset;
26057ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Offset))
26067ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach     return true;
260705d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
26087ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // The expression has to be a constant. Memory references with relocations
26097ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // don't come through here, as they use the <label> forms of the relevant
26107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // instructions.
26117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Offset);
26127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
26137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error (E, "constant expression expected");
26147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
26150da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    // If the constant was #-0, represent it as INT32_MIN.
26160da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    int32_t Val = CE->getValue();
26170da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson    if (isNegative && Val == 0)
26180da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson      CE = MCConstantExpr::Create(INT32_MIN, getContext());
26190da10cf44d0f22111dae728bb535ade2283d976bOwen Anderson
26207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Now we should have the closing ']'
26217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    E = Parser.getTok().getLoc();
26227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().isNot(AsmToken::RBrac))
26237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(E, "']' expected");
26247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat right bracket token.
262505d8b71424316ad7b014adbbb316f78c5bd46861Daniel Dunbar
26267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Don't worry about range checking the value here. That's handled by
26277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // the is*() predicates.
26287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Operands.push_back(ARMOperand::CreateMem(BaseRegNum, CE, 0,
26297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                             ARM_AM::no_shift, 0, false, S,E));
2630a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
26317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // If there's a pre-indexing writeback marker, '!', just add it as a token
26327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // operand.
26337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Parser.getTok().is(AsmToken::Exclaim)) {
26347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
26357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      Parser.Lex(); // Eat the '!'.
2636762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    }
26377ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
26387ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return false;
26399c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
2640d4462a5a4feae0293ca14376ff25d8bb72dd12a9Jim Grosbach
26417ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // The register offset is optionally preceded by a '+' or '-'
26427ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  bool isNegative = false;
26437ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Minus)) {
26447ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    isNegative = true;
26457ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '-'.
26467ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  } else if (Parser.getTok().is(AsmToken::Plus)) {
26477ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Nothing to do.
26487ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the '+'.
26497ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
26509c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
26517ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
26527ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  int OffsetRegNum = tryParseRegister();
26537ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (OffsetRegNum == -1)
26547ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "register expected");
26557ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
26567ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // If there's a shift operator, handle it.
26577ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  ARM_AM::ShiftOpc ShiftType = ARM_AM::no_shift;
26580d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach  unsigned ShiftImm = 0;
26597ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().is(AsmToken::Comma)) {
26607ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat the ','.
26610d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach    if (parseMemRegOffsetShift(ShiftType, ShiftImm))
26627ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
26639c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  }
266416c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
26657ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // Now we should have the closing ']'
26667ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  E = Parser.getTok().getLoc();
26677ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (Parser.getTok().isNot(AsmToken::RBrac))
26687ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(E, "']' expected");
26697ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Parser.Lex(); // Eat right bracket token.
26707ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
26717ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Operands.push_back(ARMOperand::CreateMem(BaseRegNum, 0, OffsetRegNum,
26720d6fac36eda6b65f0e396b24c5bce582f89f7992Jim Grosbach                                           ShiftType, ShiftImm, isNegative,
26737ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                           S, E));
26747ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach
2675f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // If there's a pre-indexing writeback marker, '!', just add it as a token
2676f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  // operand.
2677f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  if (Parser.getTok().is(AsmToken::Exclaim)) {
2678f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Operands.push_back(ARMOperand::CreateToken("!",Parser.getTok().getLoc()));
2679f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach    Parser.Lex(); // Eat the '!'.
2680f4fa3d6e463e88743983ccfa027a7555a8720917Jim Grosbach  }
26819c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
26829c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby  return false;
26839c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby}
26849c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
26857ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// parseMemRegOffsetShift - one of these two:
2686a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   ( lsl | lsr | asr | ror ) , # shift_amount
2687a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby///   rrx
26887ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach/// return true if it parses a shift otherwise it returns false.
26897ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbachbool ARMAsmParser::parseMemRegOffsetShift(ARM_AM::ShiftOpc &St,
26907ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach                                          unsigned &Amount) {
26917ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  SMLoc Loc = Parser.getTok().getLoc();
269218b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
2693a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (Tok.isNot(AsmToken::Identifier))
2694a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    return true;
269538e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef ShiftName = Tok.getString();
2696a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  if (ShiftName == "lsl" || ShiftName == "LSL")
26970082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsl;
2698a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "lsr" || ShiftName == "LSR")
26990082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::lsr;
2700a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "asr" || ShiftName == "ASR")
27010082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::asr;
2702a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "ror" || ShiftName == "ROR")
27030082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::ror;
2704a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else if (ShiftName == "rrx" || ShiftName == "RRX")
27050082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson    St = ARM_AM::rrx;
2706a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  else
27077ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    return Error(Loc, "illegal shift operator");
2708b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex(); // Eat shift type token.
2709a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
27107ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  // rrx stands alone.
27117ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  Amount = 0;
27127ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  if (St != ARM_AM::rrx) {
27137ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Loc = Parser.getTok().getLoc();
27147ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // A '#' and a shift amount.
27157ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const AsmToken &HashTok = Parser.getTok();
27167ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (HashTok.isNot(AsmToken::Hash))
27177ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(HashTok.getLoc(), "'#' expected");
27187ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Parser.Lex(); // Eat hash token.
27199c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby
27207ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCExpr *Expr;
27217ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (getParser().ParseExpression(Expr))
27227ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return true;
27237ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // Range check the immediate.
27247ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsl, ror: 0 <= imm <= 31
27257ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    // lsr, asr: 0 <= imm <= 32
27267ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
27277ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (!CE)
27287ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "shift amount must be an immediate");
27297ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    int64_t Imm = CE->getValue();
27307ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    if (Imm < 0 ||
27317ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsl || St == ARM_AM::ror) && Imm > 31) ||
27327ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach        ((St == ARM_AM::lsr || St == ARM_AM::asr) && Imm > 32))
27337ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach      return Error(Loc, "immediate shift value out of range");
27347ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach    Amount = Imm;
27357ce057983ea7b8ad42d5cca1bb5d3f6941662269Jim Grosbach  }
2736a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
2737a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  return false;
2738a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2739a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
27409c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Parse a arm instruction operand.  For now this parses the operand regardless
27419c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// of the mnemonic.
27421355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2743fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes                                StringRef Mnemonic) {
2744762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan  SMLoc S, E;
2745fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2746fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // Check if the current operand has a custom associated parser, if so, try to
2747fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes  // custom parse the operand, or fallback to the general approach.
2748f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2749f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_Success)
2750fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes    return false;
2751f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // If there wasn't a custom match, try the generic matcher below. Otherwise,
2752f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // there was a match, but an error occurred, in which case, just return that
2753f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  // the operand parsing failed.
2754f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach  if (ResTy == MatchOperand_ParseFail)
2755f922c47143d247cbae14b294a0bada139bcd35f6Jim Grosbach    return true;
2756fafde7f0b7c70e08de719d9e33ce9f6fdaefc984Bruno Cardoso Lopes
2757a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  switch (getLexer().getKind()) {
2758146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  default:
2759146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling    Error(Parser.getTok().getLoc(), "unexpected token in operand");
276050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return true;
276119906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  case AsmToken::Identifier: {
27621355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (!tryParseRegisterWithWriteBack(Operands))
276350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return false;
27640d87ec21d79c8622733b8367aa41067169602480Jim Grosbach    int Res = tryParseShiftRegister(Operands);
276519906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    if (Res == 0) // success
27660082830cb26248178fe5cc9bbdbd00881556c33dOwen Anderson      return false;
276719906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach    else if (Res == -1) // irrecoverable error
276819906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach      return true;
2769e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson
2770e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // Fall though for the Identifier case that is not a register or a
2771e4e5e2aae7e1e0e84877061432e7b981a360a77dOwen Anderson    // special name.
277219906729a490744ce3071d20e3d514cadc12e6c5Jim Grosbach  }
277367b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Integer: // things like 1f and 2b as a branch targets
277467b212e03b77e921e2b9780059681125a45d15a7Kevin Enderby  case AsmToken::Dot: {   // . as a branch target
2775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // This was not a register so parse other operands that start with an
2776515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    // identifier (like labels) as expressions and create them as immediates.
2777515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *IdVal;
2778762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(IdVal))
278050d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
2781762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
278250d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(IdVal, S, E));
278350d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
278450d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling  }
2785a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  case AsmToken::LBrac:
27861355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseMemory(Operands);
2787d7894f105a3c397a3d7f5c5136eee39f5865e64bKevin Enderby  case AsmToken::LCurly:
27881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseRegisterList(Operands);
278963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  case AsmToken::Hash: {
2790079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // #42 -> immediate.
2791079469f649d8da3923b9f747d7062c84e01cc4aeKevin Enderby    // TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
2792762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    S = Parser.getTok().getLoc();
2793b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
279463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    bool isNegative = Parser.getTok().is(AsmToken::Minus);
2795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    const MCExpr *ImmVal;
2796515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    if (getParser().ParseExpression(ImmVal))
279750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling      return true;
279863553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ImmVal);
279963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (!CE) {
280063553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      Error(S, "constant expression expected");
280163553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      return MatchOperand_ParseFail;
280263553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    }
280363553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    int32_t Val = CE->getValue();
280463553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson    if (isNegative && Val == 0)
280563553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson      ImmVal = MCConstantExpr::Create(INT32_MIN, getContext());
2806762647673379dbcff6bbba6167b0b1b0d658ba9dSean Callanan    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
280750d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    Operands.push_back(ARMOperand::CreateImm(ImmVal, S, E));
280850d0f5894448aff6eb02ad63da55ecf26b54aeb8Bill Wendling    return false;
280963553c77cd1cf3b204d955fb65350db087aaff1dOwen Anderson  }
28109081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case AsmToken::Colon: {
28119081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    // ":lower16:" and ":upper16:" expression prefixes
28127597212abced110723f2fee985a7d60557c092ecEvan Cheng    // FIXME: Check it's an expression prefix,
28137597212abced110723f2fee985a7d60557c092ecEvan Cheng    // e.g. (FOO - :lower16:BAR) isn't legal.
28147597212abced110723f2fee985a7d60557c092ecEvan Cheng    ARMMCExpr::VariantKind RefKind;
28151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parsePrefix(RefKind))
28169081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
28179081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28187597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *SubExprVal;
28197597212abced110723f2fee985a7d60557c092ecEvan Cheng    if (getParser().ParseExpression(SubExprVal))
28209081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return true;
28219081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28227597212abced110723f2fee985a7d60557c092ecEvan Cheng    const MCExpr *ExprVal = ARMMCExpr::Create(RefKind, SubExprVal,
28237597212abced110723f2fee985a7d60557c092ecEvan Cheng                                                   getContext());
28249081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
28257597212abced110723f2fee985a7d60557c092ecEvan Cheng    Operands.push_back(ARMOperand::CreateImm(ExprVal, S, E));
28269081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return false;
28279081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
2828a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
2829a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby}
2830a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
28311355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach// parsePrefix - Parse ARM 16-bit relocations expression prefix, i.e.
28327597212abced110723f2fee985a7d60557c092ecEvan Cheng//  :lower16: and :upper16:.
28331355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
28347597212abced110723f2fee985a7d60557c092ecEvan Cheng  RefKind = ARMMCExpr::VK_ARM_None;
28359081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28369081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // :lower16: and :upper16: modifiers
28378a8696db6b6f6e735bb9de630876af83946b45f9Jason W Kim  assert(getLexer().is(AsmToken::Colon) && "expected a :");
28389081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat ':'
28399081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28409081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Identifier)) {
28419081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "expected prefix identifier in operand");
28429081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
28439081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
28449081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28459081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  StringRef IDVal = Parser.getTok().getIdentifier();
28469081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (IDVal == "lower16") {
28477597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_LO16;
28489081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else if (IDVal == "upper16") {
28497597212abced110723f2fee985a7d60557c092ecEvan Cheng    RefKind = ARMMCExpr::VK_ARM_HI16;
28509081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  } else {
28519081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
28529081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
28539081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
28549081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex();
28559081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28569081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (getLexer().isNot(AsmToken::Colon)) {
28579081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    Error(Parser.getTok().getLoc(), "unexpected token after prefix");
28589081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return true;
28599081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
28609081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  Parser.Lex(); // Eat the last ':'
28619081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return false;
28629081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
28639081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28649081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kimconst MCExpr *
28651355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachARMAsmParser::applyPrefixToExpr(const MCExpr *E,
28669081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim                                MCSymbolRefExpr::VariantKind Variant) {
28679081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // Recurse over the given expression, rebuilding it to apply the given variant
28689081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  // to the leftmost symbol.
28699081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  if (Variant == MCSymbolRefExpr::VK_None)
28709081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return E;
28719081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28729081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  switch (E->getKind()) {
28739081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Target:
28749081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle target expr yet");
28759081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Constant:
28769081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle lower16/upper16 of constant yet");
28779081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28789081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::SymbolRef: {
28799081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
28809081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28819081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (SRE->getKind() != MCSymbolRefExpr::VK_None)
28829081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
28839081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28849081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCSymbolRefExpr::Create(&SRE->getSymbol(), Variant, getContext());
28859081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
28869081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28879081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Unary:
28889081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    llvm_unreachable("Can't handle unary expressions yet");
28899081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28909081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  case MCExpr::Binary: {
28919081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
28921355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    const MCExpr *LHS = applyPrefixToExpr(BE->getLHS(), Variant);
28939081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    const MCExpr *RHS = BE->getRHS();
28949081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    if (!LHS)
28959081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim      return 0;
28969081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
28979081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim    return MCBinaryExpr::Create(BE->getOpcode(), LHS, RHS, getContext());
28989081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
28999081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  }
29009081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
29019081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  assert(0 && "Invalid expression kind!");
29029081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim  return 0;
29039081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim}
29049081b4b4cf89a161246e037f4817c69de2fcdf82Jason W Kim
2905352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// \brief Given a mnemonic, split out possible predication code and carry
2906352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar/// setting letters to form a canonical mnemonic and flags.
2907352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar//
2908badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar// FIXME: Would be nice to autogen this.
290989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach// FIXME: This is a bit of a maze of special cases.
29101355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachStringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
29115f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      unsigned &PredicationCode,
29125f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach                                      bool &CarrySetting,
291389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      unsigned &ProcessorIMod,
291489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                                      StringRef &ITMask) {
2915352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  PredicationCode = ARMCC::AL;
2916352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  CarrySetting = false;
2917a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  ProcessorIMod = 0;
2918352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2919badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Ignore some mnemonics we know aren't predicated forms.
2920352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  //
2921352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // FIXME: Would be nice to autogen this.
29225f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach  if ((Mnemonic == "movs" && isThumb()) ||
29235f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "teq"   || Mnemonic == "vceq"   || Mnemonic == "svc"   ||
29245f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "mls"   || Mnemonic == "smmls"  || Mnemonic == "vcls"  ||
29255f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmls"  || Mnemonic == "vnmls"  || Mnemonic == "vacge" ||
29265f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcge"  || Mnemonic == "vclt"   || Mnemonic == "vacgt" ||
29275f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vcgt"  || Mnemonic == "vcle"   || Mnemonic == "smlal" ||
29285f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "umaal" || Mnemonic == "umlal"  || Mnemonic == "vabal" ||
29295f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal")
2930352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    return Mnemonic;
2931badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
29323f00e317064560ad11168d22030416d853829f6eJim Grosbach  // First, split out any predication code. Ignore mnemonics we know aren't
29333f00e317064560ad11168d22030416d853829f6eJim Grosbach  // predicated but do have a carry-set and so weren't caught above.
2934ab40f4b737b0a87c4048a9ad2f0c02be735e3770Jim Grosbach  if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" &&
293571725a099e6d0cba24a63f9c9063f6efee3bf76eJim Grosbach      Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" &&
293604d55f1905748b0d66655e2332e1a232a3f665f4Jim Grosbach      Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" &&
29372f25d9b9334662e846460e98a8fe2dae4f233068Jim Grosbach      Mnemonic != "sbcs" && Mnemonic != "rscs") {
29383f00e317064560ad11168d22030416d853829f6eJim Grosbach    unsigned CC = StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2))
29393f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("eq", ARMCC::EQ)
29403f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ne", ARMCC::NE)
29413f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hs", ARMCC::HS)
29423f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cs", ARMCC::HS)
29433f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lo", ARMCC::LO)
29443f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("cc", ARMCC::LO)
29453f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("mi", ARMCC::MI)
29463f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("pl", ARMCC::PL)
29473f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vs", ARMCC::VS)
29483f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("vc", ARMCC::VC)
29493f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("hi", ARMCC::HI)
29503f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ls", ARMCC::LS)
29513f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("ge", ARMCC::GE)
29523f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("lt", ARMCC::LT)
29533f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("gt", ARMCC::GT)
29543f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("le", ARMCC::LE)
29553f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Case("al", ARMCC::AL)
29563f00e317064560ad11168d22030416d853829f6eJim Grosbach      .Default(~0U);
29573f00e317064560ad11168d22030416d853829f6eJim Grosbach    if (CC != ~0U) {
29583f00e317064560ad11168d22030416d853829f6eJim Grosbach      Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2);
29593f00e317064560ad11168d22030416d853829f6eJim Grosbach      PredicationCode = CC;
29603f00e317064560ad11168d22030416d853829f6eJim Grosbach    }
296152925b60f1cd4cf810524ca05b00a207a926ab9fBill Wendling  }
2962345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
2963352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Next, determine if we have a carry setting bit. We explicitly ignore all
2964352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // the instructions we know end in 's'.
2965352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  if (Mnemonic.endswith("s") &&
296600f5d982057574cf65a4a3f29548ff9fb0ecfbd0Jim Grosbach      !(Mnemonic == "cps" || Mnemonic == "mls" ||
29675f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "mrs" || Mnemonic == "smmls" || Mnemonic == "vabs" ||
29685f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vcls" || Mnemonic == "vmls" || Mnemonic == "vmrs" ||
29695f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach        Mnemonic == "vnmls" || Mnemonic == "vqabs" || Mnemonic == "vrecps" ||
2970e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        Mnemonic == "vrsqrts" || Mnemonic == "srs" ||
2971e1cf5902ec832cecdd5a94b9701930253d410741Jim Grosbach        (Mnemonic == "movs" && isThumb()))) {
2972352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 1);
2973352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar    CarrySetting = true;
2974352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  }
2975352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar
2976a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // The "cps" instruction can have a interrupt mode operand which is glued into
2977a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // the mnemonic. Check if this is the case, split it and parse the imod op
2978a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (Mnemonic.startswith("cps")) {
2979a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    // Split out any imod code.
2980a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    unsigned IMod =
2981a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      StringSwitch<unsigned>(Mnemonic.substr(Mnemonic.size()-2, 2))
2982a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("ie", ARM_PROC::IE)
2983a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Case("id", ARM_PROC::ID)
2984a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      .Default(~0U);
2985a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    if (IMod != ~0U) {
2986a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      Mnemonic = Mnemonic.slice(0, Mnemonic.size()-2);
2987a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes      ProcessorIMod = IMod;
2988a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    }
2989a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
2990a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
299189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // The "it" instruction has the condition mask on the end of the mnemonic.
299289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic.startswith("it")) {
299389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    ITMask = Mnemonic.slice(2, Mnemonic.size());
299489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    Mnemonic = Mnemonic.slice(0, 2);
299589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
299689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
2997352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  return Mnemonic;
2998352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar}
29993771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
30003771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// \brief Given a canonical mnemonic, determine if the instruction ever allows
30013771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar/// inclusion of carry set or predication code operands.
30023771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar//
30033771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar// FIXME: It would be nice to autogen this.
3004fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopesvoid ARMAsmParser::
30051355cf1f76abe9699cd1c2838da132ff8b25b76bJim GrosbachgetMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
3006fdcee77887372dbf6589d47cc33094965b679f24Bruno Cardoso Lopes                      bool &CanAcceptPredicationCode) {
3007eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "and" || Mnemonic == "lsl" || Mnemonic == "lsr" ||
3008eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rrx" || Mnemonic == "ror" || Mnemonic == "sub" ||
3009eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "smull" || Mnemonic == "add" || Mnemonic == "adc" ||
3010eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mul" || Mnemonic == "bic" || Mnemonic == "asr" ||
3011be64b394317feb8d7bcb732bdfb35e0b286efd4cBruno Cardoso Lopes      Mnemonic == "umlal" || Mnemonic == "orr" || Mnemonic == "mvn" ||
3012eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
3013eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
30142c3f70e5d4b4f179f21ed1b2ba14674f9d65c9b0Jim Grosbach      Mnemonic == "eor" || Mnemonic == "smlal" || Mnemonic == "neg" ||
3015b80ab8e369d13673c7fec81f07d1c9718c6eec7bJim Grosbach      (Mnemonic == "mov" && !isThumb())) {
3016eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = true;
3017eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  } else {
3018eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar    CanAcceptCarrySet = false;
3019eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  }
30203771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
3021eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar  if (Mnemonic == "cbnz" || Mnemonic == "setend" || Mnemonic == "dmb" ||
3022eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "cps" || Mnemonic == "mcr2" || Mnemonic == "it" ||
3023eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
3024eb9f3f91c03c29f020ee3c25cfefe7ae2b496526Daniel Dunbar      Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
30255f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
3026c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach      Mnemonic == "setend" ||
30270780b6303b99441fef04340b7a083006484f4743Jim Grosbach      (Mnemonic == "nop" && isThumbOne()) ||
30284af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic == "pld" || Mnemonic == "pli" || Mnemonic == "pldw") &&
30294af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
30304af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach      ((Mnemonic.startswith("rfe") || Mnemonic.startswith("srs")) &&
30314af54a461fad6c98df72dd18e607bfb32bfc486fJim Grosbach       !isThumb()) ||
30325f16057d1e4b711d492091bc555693a03d4a1b6eJim Grosbach      Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
30333771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = false;
30343771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  } else {
30353771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    CanAcceptPredicationCode = true;
30363771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  }
3037fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes
3038ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng  if (isThumb())
3039fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes    if (Mnemonic == "bkpt" || Mnemonic == "mcr" || Mnemonic == "mcrr" ||
304063b46faeb8acae9b7e5f865b7417dc00b9b9dad3Jim Grosbach        Mnemonic == "mrc" || Mnemonic == "mrrc" || Mnemonic == "cdp")
3041fa5bd27fbe5188ca708ac0dda4f32d90505da9f5Bruno Cardoso Lopes      CanAcceptPredicationCode = false;
3042badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar}
3043badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3044d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbachbool ARMAsmParser::shouldOmitCCOutOperand(StringRef Mnemonic,
3045d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
304620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // FIXME: This is all horribly hacky. We really need a better way to deal
304720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // with optional operands like this in the matcher table.
3048d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3049d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // The 'mov' mnemonic is special. One variant has a cc_out operand, while
3050d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // another does not. Specifically, the MOVW instruction does not. So we
3051d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // special case it here and remove the defaulted (non-setting) cc_out
3052d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // operand if that's the instruction we're trying to match.
3053d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  //
3054d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // We do this as post-processing of the explicit operands rather than just
3055d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // conditionally adding the cc_out in the first place because we need
3056d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // to check the type of the parsed immediate operand.
3057d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  if (Mnemonic == "mov" && Operands.size() > 4 &&
3058d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      !static_cast<ARMOperand*>(Operands[4])->isARMSOImm() &&
3059d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isImm0_65535Expr() &&
3060d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
3061d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach    return true;
30623912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
30633912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
30643912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  // when there are only two register operands.
30653912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 5 &&
30663912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
30673912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
30683912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
30693912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach    return true;
307072f39f8436848885176943b0ba985a7171145423Jim Grosbach  // Register-register 'add' for thumb does not have a cc_out operand
307120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // when it's an ADD Rdm, SP, {Rdm|#imm0_255} instruction. We do
307220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // have to check the immediate range here since Thumb2 has a variant
307320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // that can handle a different range and has a cc_out operand.
307472f39f8436848885176943b0ba985a7171145423Jim Grosbach  if (isThumb() && Mnemonic == "add" && Operands.size() == 6 &&
307572f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
307672f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
307772f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->getReg() == ARM::SP &&
307820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0 &&
307920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      (static_cast<ARMOperand*>(Operands[5])->isReg() ||
308020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach       static_cast<ARMOperand*>(Operands[5])->isImm0_1020s4()))
308172f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
308220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // For Thumb2, add immediate does not have a cc_out operand for the
308320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // imm0_4096 variant. That's the least-preferred variant when
308420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // selecting via the generic "add" mnemonic, so to know that we
308520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // should remove the cc_out operand, we have to explicitly check that
308620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // it's not one of the other variants. Ugh.
308720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (isThumbTwo() && Mnemonic == "add" && Operands.size() == 6 &&
308820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
308920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[4])->isReg() &&
309020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
309120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Nest conditions rather than one big 'if' statement for readability.
309220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    //
309320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If either register is a high reg, it's either one of the SP
309420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // variants (handled above) or a 32-bit encoding, so we just
309520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // check against T3.
309620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if ((!isARMLowRegister(static_cast<ARMOperand*>(Operands[3])->getReg()) ||
309720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach         !isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg())) &&
309820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isT2SOImm())
309920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
310020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // If both registers are low, we're in an IT block, and the immediate is
310120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // in range, we should use encoding T1 instead, which has a cc_out.
310220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    if (inITBlock() &&
310320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
310420ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        isARMLowRegister(static_cast<ARMOperand*>(Operands[4])->getReg()) &&
310520ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach        static_cast<ARMOperand*>(Operands[5])->isImm0_7())
310620ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach      return false;
310720ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
310820ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // Otherwise, we use encoding T4, which does not have a cc_out
310920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    // operand.
311020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach    return true;
311120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  }
311220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
311320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach
3114f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // Register-register 'add/sub' for thumb does not have a cc_out operand
3115f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // when it's an ADD/SUB SP, #imm. Be lenient on count since there's also
3116f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // the "add/sub SP, SP, #imm" version. If the follow-up operands aren't
3117f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // right, this will result in better diagnostics (which operand is off)
3118f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  // anyway.
3119f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach  if (isThumb() && (Mnemonic == "add" || Mnemonic == "sub") &&
3120f69c80403620ef38674e037ae2664f1bbe5a4f3cJim Grosbach      (Operands.size() == 5 || Operands.size() == 6) &&
312172f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->isReg() &&
312272f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[3])->getReg() == ARM::SP &&
312372f39f8436848885176943b0ba985a7171145423Jim Grosbach      static_cast<ARMOperand*>(Operands[1])->getReg() == 0)
312472f39f8436848885176943b0ba985a7171145423Jim Grosbach    return true;
31253912b73c74dc9c928228504e9a23c577b57c4e12Jim Grosbach
3126d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  return false;
3127d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach}
3128d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach
3129badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar/// Parse an arm instruction mnemonic followed by its operands.
3130badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbarbool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc,
3131badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar                               SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3132badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  // Create the leading tokens for the mnemonic, split by '.' characters.
3133badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  size_t Start = 0, Next = Name.find('.');
3134ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  StringRef Mnemonic = Name.slice(Start, Next);
3135badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
3136352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  // Split out the predication code and carry setting flag from the mnemonic.
3137352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  unsigned PredicationCode;
3138a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  unsigned ProcessorIMod;
3139352e148cbe6498a6dd31b7fc71df7cd23c4b4d10Daniel Dunbar  bool CarrySetting;
314089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  StringRef ITMask;
31411355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  Mnemonic = splitMnemonic(Mnemonic, PredicationCode, CarrySetting,
314289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach                           ProcessorIMod, ITMask);
3143badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar
31440c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  // In Thumb1, only the branch (B) instruction can be predicated.
31450c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  if (isThumbOne() && PredicationCode != ARMCC::AL && Mnemonic != "b") {
31460c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    Parser.EatToEndOfStatement();
31470c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach    return Error(NameLoc, "conditional execution not supported in Thumb1");
31480c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach  }
31490c49ac05cd2374a99a3126ebe6c8370490a73ca5Jim Grosbach
3150ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
3151ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
315289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // Handle the IT instruction ITMask. Convert it to a bitmask. This
315389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // is the mask as it will be for the IT encoding if the conditional
315489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // encoding has a '1' as it's bit0 (i.e. 't' ==> '1'). In the case
315589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // where the conditional bit0 is zero, the instruction post-processing
315689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  // will adjust the mask accordingly.
315789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  if (Mnemonic == "it") {
3158f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + 2);
3159f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITMask.size() > 3) {
3160f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      Parser.EatToEndOfStatement();
3161f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "too many conditions on IT instruction");
3162f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
316389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = 8;
316489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    for (unsigned i = ITMask.size(); i != 0; --i) {
316589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      char pos = ITMask[i - 1];
316689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (pos != 't' && pos != 'e') {
316789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Parser.EatToEndOfStatement();
3168f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        return Error(Loc, "illegal IT block condition mask '" + ITMask + "'");
316989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      }
317089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask >>= 1;
317189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      if (ITMask[i - 1] == 't')
317289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask |= 8;
317389df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    }
3174f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    Operands.push_back(ARMOperand::CreateITMask(Mask, Loc));
317589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
317689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach
3177ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // FIXME: This is all a pretty gross hack. We should automatically handle
3178ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  // optional operands like this via tblgen.
31799717fa9f29696bca45ddfdf206b1c382c8b40b78Bill Wendling
31803771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Next, add the CCOut and ConditionCode operands, if needed.
31813771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  //
31823771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // For mnemonics which can ever incorporate a carry setting bit or predication
31833771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // code, our matching model involves us always generating CCOut and
31843771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // ConditionCode operands to match the mnemonic "as written" and then we let
31853771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // the matcher deal with finding the right instruction or generating an
31863771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // appropriate error.
31873771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  bool CanAcceptCarrySet, CanAcceptPredicationCode;
31881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach  getMnemonicAcceptInfo(Mnemonic, CanAcceptCarrySet, CanAcceptPredicationCode);
31893771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
319033c16a27370939de39679245c3dff72383c210bdJim Grosbach  // If we had a carry-set on an instruction that can't do that, issue an
319133c16a27370939de39679245c3dff72383c210bdJim Grosbach  // error.
319233c16a27370939de39679245c3dff72383c210bdJim Grosbach  if (!CanAcceptCarrySet && CarrySetting) {
319333c16a27370939de39679245c3dff72383c210bdJim Grosbach    Parser.EatToEndOfStatement();
3194ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
319533c16a27370939de39679245c3dff72383c210bdJim Grosbach                 "' can not set flags, but 's' suffix specified");
319633c16a27370939de39679245c3dff72383c210bdJim Grosbach  }
3197c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // If we had a predication code on an instruction that can't do that, issue an
3198c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  // error.
3199c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
3200c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    Parser.EatToEndOfStatement();
3201c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach    return Error(NameLoc, "instruction '" + Mnemonic +
3202c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach                 "' is not predicable, but condition code specified");
3203c27d4f9ea0cb9064d3e2cadb384d73e95e9de449Jim Grosbach  }
320433c16a27370939de39679245c3dff72383c210bdJim Grosbach
32053771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the carry setting operand, if necessary.
3206f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (CanAcceptCarrySet) {
3207f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size());
32083771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0,
3209f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                               Loc));
3210f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  }
32113771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar
32123771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  // Add the predication code operand, if necessary.
32133771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar  if (CanAcceptPredicationCode) {
3214f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    SMLoc Loc = SMLoc::getFromPointer(NameLoc.getPointer() + Mnemonic.size() +
3215f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                                      CarrySetting);
32163771dd041f6a68bef08b6f685a41d1d54f4e8b9dDaniel Dunbar    Operands.push_back(ARMOperand::CreateCondCode(
3217f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                         ARMCC::CondCodes(PredicationCode), Loc));
3218badbd2fde9b8debd6265e8ece511fb01123d1d5fDaniel Dunbar  }
3219345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar
3220a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  // Add the processor imod operand, if necessary.
3221a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  if (ProcessorIMod) {
3222a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    Operands.push_back(ARMOperand::CreateImm(
3223a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes          MCConstantExpr::Create(ProcessorIMod, getContext()),
3224a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes                                 NameLoc, NameLoc));
3225a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes  }
3226a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes
3227345a9a6269318c96f333c0492b23733e29d952dfDaniel Dunbar  // Add the remaining tokens in the mnemonic.
32285747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  while (Next != StringRef::npos) {
32295747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Start = Next;
32305747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar    Next = Name.find('.', Start + 1);
3231a2b6e4151b75248f9dbf8067186cba673520f8f4Bruno Cardoso Lopes    StringRef ExtraToken = Name.slice(Start, Next);
3232a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
32334d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // For now, we're only parsing Thumb1 (for the most part), so
32344d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // just ignore ".n" qualifiers. We'll use them to restrict
32354d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    // matching when we do Thumb2.
32364d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach    if (ExtraToken != ".n")
32374d23e99d2a272a4de06ee31eee6d8e501809a573Jim Grosbach      Operands.push_back(ARMOperand::CreateToken(ExtraToken, NameLoc));
32385747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  }
32395747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar
32405747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  // Read the remaining operands.
32415747b13af801d5af7cd5827c07c6a59e981bdb1aDaniel Dunbar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3242a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    // Read the first operand.
32431355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    if (parseOperand(Operands, Mnemonic)) {
3244cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      Parser.EatToEndOfStatement();
3245cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      return true;
3246cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    }
3247a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3248a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    while (getLexer().is(AsmToken::Comma)) {
3249b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();  // Eat the comma.
3250a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby
3251a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby      // Parse and remember the operand.
32521355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach      if (parseOperand(Operands, Mnemonic)) {
3253cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        Parser.EatToEndOfStatement();
3254cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner        return true;
3255cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner      }
3256a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby    }
3257a7ba3a81c008142a91d799e2ec3152cfd6bbb15fKevin Enderby  }
325816c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3259cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3260cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner    Parser.EatToEndOfStatement();
326134e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner    return TokError("unexpected token in argument list");
3262cbf8a98c7c652e96967623c80cb945fef001b090Chris Lattner  }
3263146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling
326434e53140c2cc02ce4c9d060e48302576d3962e1cChris Lattner  Parser.Lex(); // Consume the EndOfStatement
3265ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3266d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // Some instructions, mostly Thumb, have forms for the same mnemonic that
3267d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // do and don't have a cc_out optional-def operand. With some spot-checks
3268d54b4e612aa5d2d76a62f4409f82bd409f9af297Jim Grosbach  // of the operand list, we can figure out which variant we're trying to
326920ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // parse and adjust accordingly before actually matching. We shouldn't ever
327020ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // try to remove a cc_out operand that was explicitly set on the the
327120ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // mnemonic, of course (CarrySetting == true). Reason number #317 the
327220ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  // table driven matcher doesn't fit well with the ARM instruction set.
327320ed2e7939d6a8e804a51897c3af4588deb48be2Jim Grosbach  if (!CarrySetting && shouldOmitCCOutOperand(Mnemonic, Operands)) {
3274ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3275ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    Operands.erase(Operands.begin() + 1);
3276ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach    delete Op;
3277ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach  }
3278ffa3225e26cc1977d20f0d9649fcd6f38a3c4815Jim Grosbach
3279cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // ARM mode 'blx' need special handling, as the register operand version
3280cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // is predicable, but the label operand version is not. So, we can't rely
3281cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // on the Mnemonic based checking to correctly figure out when to put
3282cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // a CondCode operand in the list. If we're trying to match the label
3283cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  // version, remove the CondCode operand here.
3284cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  if (!isThumb() && Mnemonic == "blx" && Operands.size() == 3 &&
3285cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach      static_cast<ARMOperand*>(Operands[2])->isImm()) {
3286cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[1]);
3287cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    Operands.erase(Operands.begin() + 1);
3288cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach    delete Op;
3289cf121c35c484ee17210fde1cecbd896348cd654aJim Grosbach  }
3290857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach
3291857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // The vector-compare-to-zero instructions have a literal token "#0" at
3292857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // the end that comes to here as an immediate operand. Convert it to a
3293857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  // token to play nicely with the matcher.
3294857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  if ((Mnemonic == "vceq" || Mnemonic == "vcge" || Mnemonic == "vcgt" ||
3295857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Mnemonic == "vcle" || Mnemonic == "vclt") && Operands.size() == 6 &&
3296857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3297857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3298857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3299857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    if (CE && CE->getValue() == 0) {
3300857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.erase(Operands.begin() + 5);
3301857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3302857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach      delete Op;
3303857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach    }
3304857e1a7b3fcc848a6508f9205f22e8e0d293dcaeJim Grosbach  }
3305934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // Similarly, the Thumb1 "RSB" instruction has a literal "#0" on the
3306934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  // end. Convert it to a token here.
3307934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  if (Mnemonic == "rsb" && isThumb() && Operands.size() == 6 &&
3308934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      static_cast<ARMOperand*>(Operands[5])->isImm()) {
3309934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    ARMOperand *Op = static_cast<ARMOperand*>(Operands[5]);
3310934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op->getImm());
3311934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    if (CE && CE->getValue() == 0) {
3312934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.erase(Operands.begin() + 5);
3313934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      Operands.push_back(ARMOperand::CreateToken("#0", Op->getStartLoc()));
3314934755ac040c516eac7fdd974e87590543acd16aJim Grosbach      delete Op;
3315934755ac040c516eac7fdd974e87590543acd16aJim Grosbach    }
3316934755ac040c516eac7fdd974e87590543acd16aJim Grosbach  }
3317934755ac040c516eac7fdd974e87590543acd16aJim Grosbach
33189898671a74d3fc924347e679c45edaa685b3fe6eChris Lattner  return false;
3319ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3320ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3321189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// Validate context-sensitive operand constraints.
3322aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
3323aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// return 'true' if register list contains non-low GPR registers,
3324aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'false' otherwise. If Reg is in the register list or is HiReg, set
3325aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach// 'containsReg' to true.
3326aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbachstatic bool checkLowRegisterList(MCInst Inst, unsigned OpNo, unsigned Reg,
3327aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                                 unsigned HiReg, bool &containsReg) {
3328aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  containsReg = false;
3329aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
3330aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    unsigned OpReg = Inst.getOperand(i).getReg();
3331aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (OpReg == Reg)
3332aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      containsReg = true;
3333aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    // Anything other than a low register isn't legal here.
3334aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!isARMLowRegister(OpReg) && (!HiReg || OpReg != HiReg))
3335aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return true;
3336aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  }
3337aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach  return false;
3338aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach}
3339aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach
3340f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
3341f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// the ARMInsts array) instead. Getting that here requires awkward
3342f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach// API changes, though. Better way?
3343f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachnamespace llvm {
3344f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachextern MCInstrDesc ARMInsts[];
3345f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
3346f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbachstatic MCInstrDesc &getInstDesc(unsigned Opcode) {
3347f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  return ARMInsts[Opcode];
3348f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach}
3349f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3350189610f9466686a91fb7d847b572e1645c785323Jim Grosbach// FIXME: We would really like to be able to tablegen'erate this.
3351189610f9466686a91fb7d847b572e1645c785323Jim Grosbachbool ARMAsmParser::
3352189610f9466686a91fb7d847b572e1645c785323Jim GrosbachvalidateInstruction(MCInst &Inst,
3353189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3354f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
3355f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  SMLoc Loc = Operands[0]->getStartLoc();
3356f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  // Check the IT block state first.
3357f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  if (inITBlock()) {
3358f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned bit = 1;
3359f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (ITState.FirstCond)
3360f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ITState.FirstCond = false;
3361f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    else
3362a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
3363f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // The instruction must be predicable.
3364f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (!MCID.isPredicable())
3365f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(Loc, "instructions in IT block must be predicable");
3366f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned Cond = Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm();
3367f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned ITCond = bit ? ITState.Cond :
3368f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      ARMCC::getOppositeCondition(ITState.Cond);
3369f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (Cond != ITCond) {
3370f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      // Find the condition code Operand to get its SMLoc information.
3371f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      SMLoc CondLoc;
3372f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      for (unsigned i = 1; i < Operands.size(); ++i)
3373f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        if (static_cast<ARMOperand*>(Operands[i])->isCondCode())
3374f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach          CondLoc = Operands[i]->getStartLoc();
3375f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Error(CondLoc, "incorrect condition in IT block; got '" +
3376f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   StringRef(ARMCondCodeToString(ARMCC::CondCodes(Cond))) +
3377f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   "', but expected '" +
3378f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach                   ARMCondCodeToString(ARMCC::CondCodes(ITCond)) + "'");
3379f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    }
3380c9a9b442853ee086492d6ad1384a2de2fea9b43bJim Grosbach  // Check for non-'al' condition codes outside of the IT block.
3381f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  } else if (isThumbTwo() && MCID.isPredicable() &&
3382f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach             Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() !=
33837f17b5a483ea358f2b9e3958f16cf34d75d5b4daOwen Anderson             ARMCC::AL && Inst.getOpcode() != ARM::tBcc &&
33847f17b5a483ea358f2b9e3958f16cf34d75d5b4daOwen Anderson             Inst.getOpcode() != ARM::t2Bcc)
3385f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(Loc, "predicated instructions must be in IT block");
3386f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3387189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  switch (Inst.getOpcode()) {
33882fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD:
33892fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_PRE:
33902fd2b87ded53f6b87eb240c17d62a23fb4964ba0Jim Grosbach  case ARM::LDRD_POST:
3391189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::LDREXD: {
3392189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3393189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
3394189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3395189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
3396189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3397189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "destination operands must be sequential");
3398189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3399189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
340014605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  case ARM::STRD: {
340114605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    // Rt2 must be Rt + 1.
340214605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
340314605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
340414605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    if (Rt2 != Rt + 1)
340514605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
340614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach                   "source operands must be sequential");
340714605d1a679d55ff25875656e100ff455194ee17Jim Grosbach    return false;
340814605d1a679d55ff25875656e100ff455194ee17Jim Grosbach  }
340953642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_PRE:
341053642c533564c41d9a85ad28efe19b12fc2305ceJim Grosbach  case ARM::STRD_POST:
3411189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  case ARM::STREXD: {
3412189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Rt2 must be Rt + 1.
3413189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
3414189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
3415189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    if (Rt2 != Rt + 1)
341614605d1a679d55ff25875656e100ff455194ee17Jim Grosbach      return Error(Operands[3]->getStartLoc(),
3417189610f9466686a91fb7d847b572e1645c785323Jim Grosbach                   "source operands must be sequential");
3418189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    return false;
3419189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3420fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::SBFX:
3421fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  case ARM::UBFX: {
3422fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    // width must be in range [1, 32-lsb]
3423fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned lsb = Inst.getOperand(2).getImm();
3424fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    unsigned widthm1 = Inst.getOperand(3).getImm();
3425fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach    if (widthm1 >= 32 - lsb)
3426fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach      return Error(Operands[5]->getStartLoc(),
3427fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach                   "bitfield width must be in range [1,32-lsb]");
342800c9a518886c4f2d1cd869c174c994c20a353906Jim Grosbach    return false;
3429fb8989e64024547e4ad5ab6fe4d94fe146a7899fJim Grosbach  }
343093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  case ARM::tLDMIA: {
343193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // Thumb LDM instructions are writeback iff the base register is not
343293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // in the register list.
343393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    unsigned Rn = Inst.getOperand(0).getReg();
34347260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    bool hasWritebackToken =
34357260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      (static_cast<ARMOperand*>(Operands[3])->isToken() &&
34367260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach       static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
3437aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3438aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase))
3439aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
3440aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7");
344193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    // If we should have writeback, then there should be a '!' token.
3442aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (!listContainsBase && !hasWritebackToken)
344393b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach      return Error(Operands[2]->getStartLoc(),
344493b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach                   "writeback operator '!' expected");
34457260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach    // Likewise, if we should not have writeback, there must not be a '!'
3446aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (listContainsBase && hasWritebackToken)
34477260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach      return Error(Operands[3]->getStartLoc(),
34487260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "writeback operator '!' not allowed when base register "
34497260c6a4ea19f5eb94068296c1c8e01a99f17a01Jim Grosbach                   "in register list");
345093b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach
345193b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach    break;
345293b3eff62322803a520e183fdc294bffd6d99bfaJim Grosbach  }
34536dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPOP: {
3454aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3455aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
3456aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3457aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or pc");
34586dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
34596dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
34606dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  case ARM::tPUSH: {
3461aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    bool listContainsBase;
3462aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach    if (checkLowRegisterList(Inst, 3, 0, ARM::LR, listContainsBase))
3463aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach      return Error(Operands[2]->getStartLoc(),
3464aa875f8c6fdf3a7a26ccc381cf8ecd2b69678dadJim Grosbach                   "registers must be in range r0-r7 or lr");
34656dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach    break;
34666dcafc0d0b33bebcac28539257a9a5b250542f6aJim Grosbach  }
34671e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  case ARM::tSTMIA_UPD: {
34681e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    bool listContainsBase;
3469f95aaf951b628621c9c74bed6c450b8a52a1ae1eJim Grosbach    if (checkLowRegisterList(Inst, 4, 0, 0, listContainsBase))
34701e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach      return Error(Operands[4]->getStartLoc(),
34711e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach                   "registers must be in range r0-r7");
34721e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach    break;
34731e84f19337d44c04e74af4fb005550b525ef60e5Jim Grosbach  }
3474189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  }
3475189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3476189610f9466686a91fb7d847b572e1645c785323Jim Grosbach  return false;
3477189610f9466686a91fb7d847b572e1645c785323Jim Grosbach}
3478189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3479f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbachvoid ARMAsmParser::
3480f8fce711e8b756adca63044f7d122648c960ab96Jim GrosbachprocessInstruction(MCInst &Inst,
3481f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach                   const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
3482f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  switch (Inst.getOpcode()) {
3483f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  case ARM::LDMIA_UPD:
3484f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // If this is a load of a single register via a 'pop', then we should use
3485f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // a post-indexed LDR instruction instead, per the ARM ARM.
3486f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "pop" &&
3487f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach        Inst.getNumOperands() == 5) {
3488f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      MCInst TmpInst;
3489f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.setOpcode(ARM::LDR_POST_IMM);
3490f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
3491f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
3492f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // Rn
3493f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));  // am2offset
3494f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
3495f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
3496f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3497f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach      Inst = TmpInst;
3498f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    }
3499f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    break;
3500f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach  case ARM::STMDB_UPD:
3501f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // If this is a store of a single register via a 'push', then we should use
3502f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    // a pre-indexed STR instruction instead, per the ARM ARM.
3503f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    if (static_cast<ARMOperand*>(Operands[0])->getToken() == "push" &&
3504f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach        Inst.getNumOperands() == 5) {
3505f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      MCInst TmpInst;
3506f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.setOpcode(ARM::STR_PRE_IMM);
3507f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
3508f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(4)); // Rt
3509f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(1)); // addrmode_imm12
3510f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(-4));
3511f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(2)); // CondCode
3512f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      TmpInst.addOperand(Inst.getOperand(3));
3513f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach      Inst = TmpInst;
3514f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    }
3515f6713916fb4504aab617f0e317689acd878cc37fJim Grosbach    break;
351689e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach  case ARM::tADDi8:
35170f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // If the immediate is in the range 0-7, we want tADDi3 iff Rd was
35180f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // explicitly specified. From the ARM ARM: "Encoding T1 is preferred
35190f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T2 if <Rd> is specified and encoding T2 is preferred
35200f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    // to encoding T1 if <Rd> is omitted."
35210f3abd8d68cfb4a0705d0a8140d7f7dce32f6e77Jim Grosbach    if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)
352289e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach      Inst.setOpcode(ARM::tADDi3);
352389e2aa6afd408f1b4c6b47c53bbf31d48463bcabJim Grosbach    break;
3524c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach  case ARM::t2Bcc:
3525a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // If the conditional is AL or we're in an IT block, we really want t2B.
3526a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
3527c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach      Inst.setOpcode(ARM::t2B);
3528c075510e43f768e79f0d66374f4d60529c4d3d85Jim Grosbach    break;
3529395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach  case ARM::tBcc:
3530395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    // If the conditional is AL, we really want tB.
3531395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach    if (Inst.getOperand(1).getImm() == ARMCC::AL)
3532395b453bed53a60c559b679eb92f75d0b140b307Jim Grosbach      Inst.setOpcode(ARM::tB);
35333ce23d3d87d1ca437acb65ac01fac1c486507280Jim Grosbach    break;
353489df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  case ARM::t2IT: {
353589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // The mask bits for all but the first condition are represented as
353689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // the low bit of the condition code value implies 't'. We currently
353789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // always have 1 implies 't', so XOR toggle the bits if the low bit
353889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // of the condition code is zero. The encoding also expects the low
353989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // bit of the condition to be encoded as bit 4 of the mask operand,
354089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    // so mask that in if needed
354189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MCOperand &MO = Inst.getOperand(1);
354289df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    unsigned Mask = MO.getImm();
3543f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned OrigMask = Mask;
3544f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    unsigned TZ = CountTrailingZeros_32(Mask);
354589df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    if ((Inst.getOperand(0).getImm() & 1) == 0) {
354689df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      assert(Mask && TZ <= 3 && "illegal IT mask value!");
354789df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      for (unsigned i = 3; i != TZ; --i)
354889df996ab20609676ecc8823f58414d598b09b46Jim Grosbach        Mask ^= 1 << i;
354989df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    } else
355089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach      Mask |= 0x10;
355189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    MO.setImm(Mask);
3552f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach
3553f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // Set up the IT block state according to the IT instruction we just
3554f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    // matched.
3555f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    assert(!inITBlock() && "nested IT blocks?!");
3556f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Cond = ARMCC::CondCodes(Inst.getOperand(0).getImm());
3557f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.Mask = OrigMask; // Use the original mask, not the updated one.
3558f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.CurPosition = 0;
3559f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    ITState.FirstCond = true;
356089df996ab20609676ecc8823f58414d598b09b46Jim Grosbach    break;
356189df996ab20609676ecc8823f58414d598b09b46Jim Grosbach  }
3562f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach  }
3563f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach}
3564f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
356547a0d52b69056250a1edaca8b28f705993094542Jim Grosbachunsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
356647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // 16-bit thumb arithmetic instructions either require or preclude the 'S'
356747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  // suffix depending on whether they're in an IT block or not.
3568194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  unsigned Opc = Inst.getOpcode();
3569194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  MCInstrDesc &MCID = getInstDesc(Opc);
357047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
357147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.hasOptionalDef() &&
357247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "optionally flag setting instruction missing optional def operand");
357347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    assert(MCID.NumOperands == Inst.getNumOperands() &&
357447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach           "operand count mismatch!");
357547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // Find the optional-def operand (cc_out).
357647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    unsigned OpNo;
357747a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    for (OpNo = 0;
357847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
357947a0d52b69056250a1edaca8b28f705993094542Jim Grosbach         ++OpNo)
358047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      ;
358147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb1, reject it completely.
358247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
358347a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_MnemonicFail;
358447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // If we're parsing Thumb2, which form is legal depends on whether we're
358547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    // in an IT block.
3586f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR &&
3587f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        !inITBlock())
358847a0d52b69056250a1edaca8b28f705993094542Jim Grosbach      return Match_RequiresITBlock;
3589f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() == ARM::CPSR &&
3590f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach        inITBlock())
3591f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach      return Match_RequiresNotITBlock;
359247a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  }
3593194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Some high-register supporting Thumb1 encodings only allow both registers
3594194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // to be from r0-r7 when in Thumb2.
3595194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  else if (Opc == ARM::tADDhirr && isThumbOne() &&
3596194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()) &&
3597194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(2).getReg()))
3598194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresThumb2;
3599194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  // Others only require ARMv6 or later.
36004ec6e888ec6d12b5255afd685b05c8fee1f7fc73Jim Grosbach  else if (Opc == ARM::tMOVr && isThumbOne() && !hasV6Ops() &&
3601194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(0).getReg()) &&
3602194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach           isARMLowRegister(Inst.getOperand(1).getReg()))
3603194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Match_RequiresV6;
360447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  return Match_Success;
360547a0d52b69056250a1edaca8b28f705993094542Jim Grosbach}
360647a0d52b69056250a1edaca8b28f705993094542Jim Grosbach
3607fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattnerbool ARMAsmParser::
3608fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris LattnerMatchAndEmitInstruction(SMLoc IDLoc,
3609fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
3610fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner                        MCStreamer &Out) {
3611fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  MCInst Inst;
3612fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  unsigned ErrorInfo;
361319cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  unsigned MatchResult;
3614193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
3615193c3acbe5cdb60767d114016970e898c7502d7aKevin Enderby  switch (MatchResult) {
361619cb7f491fbc7cb5d0bbd10e201f9d5093e6d4e5Jim Grosbach  default: break;
3617e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_Success:
3618189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // Context sensitive operand constraints aren't handled by the matcher,
3619189610f9466686a91fb7d847b572e1645c785323Jim Grosbach    // so check them here.
3620a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    if (validateInstruction(Inst, Operands)) {
3621a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // Still progress the IT block, otherwise one wrong condition causes
3622a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      // nasty cascading errors.
3623a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach      forwardITPosition();
3624189610f9466686a91fb7d847b572e1645c785323Jim Grosbach      return true;
3625a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    }
3626189610f9466686a91fb7d847b572e1645c785323Jim Grosbach
3627f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // Some instructions need post-processing to, for example, tweak which
3628f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    // encoding is selected.
3629f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach    processInstruction(Inst, Operands);
3630f8fce711e8b756adca63044f7d122648c960ab96Jim Grosbach
3631a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // Only move forward at the very end so that everything in validate
3632a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // and process gets a consistent answer about whether we're in an IT
3633a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    // block.
3634a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach    forwardITPosition();
3635a110988b391652e3f4f85cb709a3eeb81c8cdd84Jim Grosbach
3636fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    Out.EmitInstruction(Inst);
3637fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner    return false;
3638e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MissingFeature:
3639e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3640e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return true;
3641e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_InvalidOperand: {
3642e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    SMLoc ErrorLoc = IDLoc;
3643e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    if (ErrorInfo != ~0U) {
3644e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorInfo >= Operands.size())
3645e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner        return Error(IDLoc, "too few operands for instruction");
364616c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3647e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      ErrorLoc = ((ARMOperand*)Operands[ErrorInfo])->getStartLoc();
3648e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
3649e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    }
365016c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3651e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner    return Error(ErrorLoc, "invalid operand for instruction");
3652e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  }
3653e73d4f8ec7af68fc0f67811e4e004562ab538014Chris Lattner  case Match_MnemonicFail:
365447a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "invalid instruction");
3655b412915ff6229b3e2dffedcfb0f3fb7e85259841Daniel Dunbar  case Match_ConversionFail:
365688ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    // The converter function will have already emited a diagnostic.
365788ae2bc6d53bbf58422ff74729da18a53e155b4aJim Grosbach    return true;
3658f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach  case Match_RequiresNotITBlock:
3659f8e1e3e729473b8b2b7ee6134b6417976af84d05Jim Grosbach    return Error(IDLoc, "flag setting instruction only valid outside IT block");
366047a0d52b69056250a1edaca8b28f705993094542Jim Grosbach  case Match_RequiresITBlock:
366147a0d52b69056250a1edaca8b28f705993094542Jim Grosbach    return Error(IDLoc, "instruction only valid inside IT block");
3662194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresV6:
3663194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires ARMv6 or later");
3664194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach  case Match_RequiresThumb2:
3665194bd8982936c819a4b14335a4d08f28af8f3d42Jim Grosbach    return Error(IDLoc, "instruction variant requires Thumb2");
3666fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner  }
366716c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3668c223e2b10b4753a63dfe7e6980c650b179139983Eric Christopher  llvm_unreachable("Implement any new match types added!");
3669146018fc6414eb2a1e67b2d8798a42a2f55ec96cBill Wendling  return true;
3670fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner}
3671fa42fad8bf7b0058ba031a275e1e8ce53b2cb1adChris Lattner
36721355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirective parses the arm specific directives
3673ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbybool ARMAsmParser::ParseDirective(AsmToken DirectiveID) {
3674ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  StringRef IDVal = DirectiveID.getIdentifier();
3675ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (IDVal == ".word")
36761355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveWord(4, DirectiveID.getLoc());
3677515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb")
36781355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumb(DirectiveID.getLoc());
3679515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".thumb_func")
36801355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveThumbFunc(DirectiveID.getLoc());
3681515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".code")
36821355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveCode(DirectiveID.getLoc());
3683515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else if (IDVal == ".syntax")
36841355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach    return parseDirectiveSyntax(DirectiveID.getLoc());
3685ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return true;
3686ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3687ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
36881355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveWord
3689ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby///  ::= .word [ expression (, expression)* ]
36901355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
3691ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement)) {
3692ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    for (;;) {
3693ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      const MCExpr *Value;
3694ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getParser().ParseExpression(Value))
3695ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return true;
3696ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3697aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner      getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
3698ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3699ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().is(AsmToken::EndOfStatement))
3700ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        break;
370116c7425cff6ac3d0a4a9c56779bdfa91b2e8e863Jim Grosbach
3702ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      // FIXME: Improve diagnostic.
3703ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby      if (getLexer().isNot(AsmToken::Comma))
3704ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby        return Error(L, "unexpected token in directive");
3705b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan      Parser.Lex();
3706ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby    }
3707ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  }
3708ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
3709b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3710ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby  return false;
3711ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
3712ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby
37131355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumb
3714515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumb
37151355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
3716515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
3717515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
3718b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3719515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3720515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: set thumb mode
3721515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO: tell the MC streamer the mode
3722515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
3723515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3724515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3725515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
37261355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveThumbFunc
3727515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .thumbfunc symbol_name
37281355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) {
37296469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
37306469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  bool isMachO = MAI.hasSubsectionsViaSymbols();
37316469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  StringRef Name;
37326469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
37336469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // Darwin asm has function name after .thumb_func direction
37346469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // ELF doesn't
37356469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (isMachO) {
37366469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    const AsmToken &Tok = Parser.getTok();
37376469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
37386469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola      return Error(L, "unexpected token in .thumb_func directive");
37396469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Tok.getString();
37406469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Parser.Lex(); // Consume the identifier token.
37416469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
37426469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
3743515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
3744515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in directive");
3745b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3746515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
37476469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  // FIXME: assuming function name will be the line following .thumb_func
37486469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  if (!isMachO) {
37496469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola    Name = Parser.getTok().getString();
37506469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola  }
37516469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola
3752642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  // Mark symbol as a thumb symbol.
3753642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
3754642fc9c24ba7c43a4a962c6c05cfffce713d7de7Jim Grosbach  getParser().getStreamer().EmitThumbFunc(Func);
3755515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3756515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3757515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
37581355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveSyntax
3759515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .syntax unified | divided
37601355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveSyntax(SMLoc L) {
376118b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3762515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Identifier))
3763515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .syntax directive");
376438e59891ee4417a9be2f8146ce0ba3269e38ac21Benjamin Kramer  StringRef Mode = Tok.getString();
376558c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Mode == "unified" || Mode == "UNIFIED")
3766b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
376758c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Mode == "divided" || Mode == "DIVIDED")
37689e56fb12c504c82c92947fe9c46287fc60116b91Kevin Enderby    return Error(L, "'.syntax divided' arm asssembly not supported");
3769515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
3770515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unrecognized syntax mode in .syntax directive");
3771515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3772515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
377318b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
3774b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3775515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3776515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // TODO tell the MC streamer the mode
3777515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  // getParser().getStreamer().Emit???();
3778515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3779515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3780515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
37811355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbach/// parseDirectiveCode
3782515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby///  ::= .code 16 | 32
37831355cf1f76abe9699cd1c2838da132ff8b25b76bJim Grosbachbool ARMAsmParser::parseDirectiveCode(SMLoc L) {
378418b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  const AsmToken &Tok = Parser.getTok();
3785515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (Tok.isNot(AsmToken::Integer))
3786515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "unexpected token in .code directive");
378718b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan  int64_t Val = Parser.getTok().getIntVal();
378858c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  if (Val == 16)
3789b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
379058c86910b31c569a5709466c82e2fabae2014a56Duncan Sands  else if (Val == 32)
3791b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan    Parser.Lex();
3792515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  else
3793515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby    return Error(L, "invalid operand to .code directive");
3794515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
3795515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  if (getLexer().isNot(AsmToken::EndOfStatement))
379618b8323de70e3461b5d035e3f9e4f6dfaf5e674bSean Callanan    return Error(Parser.getTok().getLoc(), "unexpected token in directive");
3797b9a25b7744ed12b80031426978decce3d4cebbd7Sean Callanan  Parser.Lex();
3798515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
379932869205052430f45d598fba25ab878d8b29da2dEvan Cheng  if (Val == 16) {
380098447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (!isThumb())
3801ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
380298447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
380332869205052430f45d598fba25ab878d8b29da2dEvan Cheng  } else {
380498447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    if (isThumb())
3805ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng      SwitchMode();
380698447daa9559d5bf7816f084581b5ca073d316f6Jim Grosbach    getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
3807eb0caa115491019f7f7fe45fc70ad47682244187Evan Cheng  }
38082a301704ea76535f0485d5c3b75664b323249bdbJim Grosbach
3809515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby  return false;
3810515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby}
3811515d509360d81946247fd0f937034cdf1f237c72Kevin Enderby
381290b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callananextern "C" void LLVMInitializeARMAsmLexer();
381390b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan
38149c41fa87eac369d84f8bfc2245084cd39f281ee4Kevin Enderby/// Force static initialization.
3815ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderbyextern "C" void LLVMInitializeARMAsmParser() {
381694b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> X(TheARMTarget);
381794b9550a32d189704a8eae55505edf62662c0534Evan Cheng  RegisterMCAsmParser<ARMAsmParser> Y(TheThumbTarget);
381890b7097f92f6b4f6b27cd88c7c88a21b777f5795Sean Callanan  LLVMInitializeARMAsmLexer();
3819ca9c42c4daa8f4ffd9411e11c05fb53ee1bfaf70Kevin Enderby}
38203483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar
38210692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_REGISTER_MATCHER
38220692ee676f8cdad25ad09a868bf597af4115c9d9Chris Lattner#define GET_MATCHER_IMPLEMENTATION
38233483acabf012b847b13b969ebd9ce5c4d16d9eb7Daniel Dunbar#include "ARMGenAsmMatcher.inc"
3824